I have the DRV8434S working great with a stepper motor, using the Arduino driver. The only problem I have is detecting a disconnected motor. I cannot get the OL bit on the FAULT register to set when the motor is disconnected. I have tried:
sd->setReg(DRV8434SRegAddr::CTRL4,0x38); // Enable the Open Load (OL) Fault bit
uint8_t fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
The byte printed is always zero.
Driving the motor 20 steps (no microstepping) does not help.
Suggestions?
Have you been able to successfully read any other data from the driver? If you call the verifySettings() function in your program, does it return true?
Also, could you post some pictures showing your connections and soldering? What do you have the driver’s current limit set to?
I had to go look at my code. I don’t think I query the driver for any other information. The object that I use as a wrapper around the driver only sends commands. I have not tried verifySettings(). I can try it.
I have good control of the driver current. The current limit is set to 0.68 V (maximum current 514 mA). I send current limit commands to the driver using setCurrentMilliamps(). I use 386 mA (75%) to find the zero position of the device being controlled. (I force a stall.) Most movements after that are at 418 mA (81.25%). Average current draw has been confirmed with a digital power supply.
I have included 3 pictures. #1 is a close-up of the soldering of the DRV8434S headers. #2 is the test configuration. #3 is the same circuit on the PCB I designed for the final application. The PCB version behaves like the prototype over many of the programmed functions, but I have not compared them closely. All the development is on the protoboard.
Serial.println(" Clear faults");
sd->clearFaults(); // Clear any faults
fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
Serial.println(" Clear faults");
sd->clearFaults(); // Clear any faults
fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
if (sd->verifySettings()) {
Serial.println(" Settings verified");
}
else {
Serial.println(" Settings not verified");
sd->applySettings() ;
}
if (sd->verifySettings()) {
Serial.println(" Settings verified");
}
else {
Serial.println(" Settings not verified");
}
Serial.println(" Enable Fault-on-OL");
sd->setReg(DRV8434SRegAddr::CTRL4,0x38); // Enable the Open Load (OL) Fault bit
if (sd->verifySettings()) {
Serial.println(" Write to CTRL4 verified");
}
else {
Serial.println(" Settings not verified after write to CTRL4");
}
fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
Serial.println(" Clear faults again");
sd->clearFaults(); // Clear any faults
fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
Serial.println(" Try moving the motor");
// Try to move the motor
// 20 steps. CW direction is relatively safe
// full steps, 2ms between steps
sd->setStepMode(1);
sd->setDirection(CW_Direction);
// Move motor 20 steps
for(int step_count = 0; step_count < 20; step_count++) {
sd->step(); // Move one step
delayMicroseconds(2000); // Pause before next step
}
fault_status_byte = sd->readFault(); // fetch the fault register
Serial.print (" FAULT Status byte "); Serial.println(fault_status_byte,HEX);
disconnected = (fault_status_byte & 0x01) ;
if (disconnected) {
Serial.println(" Motor not connected");
}
else {
Serial.println(" Motor is connected");
}
Stepmotor::MotorConnected check for motor connection
FAULT Status byte 0
Enable driver
Motor on
FAULT Status byte 0
Set current limit
Clear faults
FAULT Status byte 0
Settings not verified
Settings not verified
Enable Fault-on-OL
Settings not verified after write to CTRL4
FAULT Status byte 0
Clear faults again
FAULT Status byte 0
Try moving the motor
FAULT Status byte 0
Motor is connected
readFault() and verifySettings() are returning zero for reasons that I have yet to understand.
Suggestions?
As a reminder, the commands I issue to the motor (e.g., setCurrentMilliamps(), setStepMode(), enableSPIDirection(), step(), etc) all seem to work well.
All of the commands you mention that are working correctly are only “write” commands, while the readFault() and verifySettings() commands are “read” commands. So, I suspect the problem might be with the SDO line. Could you double check your connection to the SDO pin on the DRV8434S carrier, and also tell us what pin it is connected to on your Adafruit Feather RP2040? Also, could you check the SDO line with an oscilloscope and post some screen captures of it?
Thank you for your continued support.
The SPI port connections:
DRV8434S Feather RP2040
SDO MI/GP20
SDI MO/GP19
SCLK SCK/GP18
These connections have been verified on the prototype (protoboard).
Here is a scope image of SPI data. Sorry about the cellphone capture.
Top trace is the clock
Middle trace is MI/GP20 (SDO of the driver)
The bottom trace is MO/GP19 (SDI of the driver)
I do not see any obvious problems with the SDO signal; have you gotten other SPI devices working with that board before (including reading from them)? Do you have another Feather RP2040 board that you can try swapping in (in case it’s a problem with the MISO pin on it)?
I’m not sure what else could be causing the issue, but if you post your full code we could take a look and see if anything stands out.
Brandon,
I have not tried to run other SPI devices with the Feather RP2040. I recently purchased an Adafruit SPI non-volatile FRAM breakout board. I can test that. I have plenty of spare Feather boards, so I can swap that out. I can also run a test program to see if GPIO 20 is working.
The code is fairly involved and still beta. I don’t think I would post it, but perhaps there is some other mechanism for more private sharing, if necessary.
Thank you for the review. A bad I/O bit is very possible. I will find out.
Right now GPIO 9 is connected to the N_FAULT bit. I do not use it, but I could use the N_FAULT bit just to see if the FAULT condition is raised (bit = 0) when the motor is disconnected. Assuming my write to CTRL4 is working properly, I should see the FAULT only when Fault-on-OL is enabled. Is that correct?
Using the nFAULT pin to verify that the open load detection was enabled successfully (by setting the EN_OL bit to 1) probably won’t be very conclusive since there are many other conditions that can cause the nFAULT pin to be driven low.
Replacing the processor did not solve the problem. I understand the limitations of using the nFAULT bit, but it could be useful for Power On Self Test to flag a possible disconnected cable.
I will be out of the lab for a few weeks, but this is plan.
Carefully check the initialization code for conflicts with the MI (MISO). That pin is also GPIO 20 and there is an opportunity to confuse the SPI port. If necessary, I will wire a much reduced breadboard with minimal startup and test code.
Implement a SPI FRAM test to independently verify that the processor SPI is working properly. I need experience with external non-volatile memory. The RP2040 lacks EEPROM.
Your support has been a valuable sanity check. Thank you.