Following my issues when I was running the motor TMC2300-IOT-REF - Remote controlled Stepper Motor - Getting your motor running we've had some advice from Trinamic regarding, how to ensure the motor is stopped before unplugging the motor and how to communicate with the motor.
Following the advice from Trinamic, I reset the board as follows:
Steps to shut off the system (if something misbehaves):
- Push and hold the RESET pin
- Disconnect the battery
The next steps were described as follows:
Steps to start turning the motor with the TMC2300. Only move the motor with the battery connected!
- Keep the EN pin pulled low
- Pull the IO5 pin low to enable VCC_IO supply for the TMC2300
- Read the IFCNT register (address 0x02) - and verify that you received a reply with a valid CRC
- Write the IHOLD_IRUN register (address 0x10). Suggested: Reduce the run current to a lower value for now, e.g. 10 instead of the default 31.
- Read the IFCNT register (address 0x02) again to verify that the write to IHOLD_IRUN was successful
- Pull the EN pin high
- Move the motor by either pulsing the STEP pin or setting a nonzero value in the VACTUAL register (address 0x22)
I also reviewed the code from navadeepganeshu and robertogp but I wanted to see the motor move under serial control rather than step and direction so dug a bit more into the code. And I experimented with writing and then reading the hold current and other registers. But the chip did not seem to respond with any data, I failed at step 3.
After a while I came across the address that was used to determine which slave would respond to the microcontroller. Looking at the schematic for the IOT board, both of these are low.
However, in the TMC_2300.ino example code this value was 3.
void tmc2300_writeInt(uint8_t address, int32_t value) { uint8_t data[8]; data[0] = 0x05; data[1] = 3; // The Address of the slave data[2] = address | TMC_WRITE_BIT; data[3] = (value >> 24) & 0xFF; data[4] = (value >> 16) & 0xFF; data[5] = (value >> 8 ) & 0xFF; data[6] = (value ) & 0xFF; data[7] = tmc_CRC8(data, 7, 0); tmc2300_readWriteArray(&data[0], 8, 0); }
Setting that to 0 for both read and write meant that I now started getting values back when I read the TMC2300_GCONF and TMC2300_IOIN registers that seemed to tally to the data sheets. I also tried reading from the IFCNT register but so no data there.
Register | Value |
---|---|
GSTAT | 0000000000000001 |
GCONF | 0000000001000000 |
IOIN | 0000000001100010 |
IHOLD_IRUN | 0000000000000000 |
However, the register for IHOLD_IRUN seemed to be blank, even though I was writing it to was 0000101000001000
Re-reading the datasheet. It would appear that several of the registers including IHOLD_IRUN are write only. Hence we can expect to get zeros back. If you look at some of the code libraries such as https://github.com/trinamic/TMC-API their approach is to record the values as they are set so you can read back the values.
Given that it would seem that the chip was communicating as intended, I finally took the plunge and enabled the motor with:
tmc2300_writeInt(TMC2300_VACTUAL, 25000); digitalWrite(MOTOR_EN, HIGH);
However, this seemed to cause some problems with the serial communication. Note that I'd modified the CRC checks to return why the checks were failing when I was trying to diagnose the issue with the address above.
GCONF:Master Address Fail
0000000000000000
IOIN:Sync Nibble Fail
0000000000000000
I experimented with different baud rates but this didn't seem to help, so I've reverted back to 115200.
So it does seem to be working now of a fashion but there are still issues. Note that my board still gets very hot so that may be the reason why it is not behaving.
Code at: https://github.com/Workshopshed/TMC2300-IOT-Roadtest