MotorDriver / L6474

Stepper motor driver library for Arduino Uno using X-NUCLEO-IHM01A1 shield (based on L6474 component)
10 stars 7 forks source link

GetStatus() always returning zero. #4

Open J-Dunn opened 9 years ago

J-Dunn commented 9 years ago

Initial testing of L6474 on GRBL derived from this library always a status register of zero so I came back to the three shield demo to start tracing where I went wrong. However, I find that the demo also returns zero staus even when I deliberately create and under-voltage error by putting 5V on Vin .

The shields' LEDs ( D2 ) light up indicating the error condition but

In L6474::Begin() just after setting up the SPI and PWM registers I added some debugging output:

   case 1:
      pinMode(L6474_DIR_1_Pin, OUTPUT);
      pinMode(L6474_PWM_1_Pin, OUTPUT);
      PwmInit(0);
    default:
      ;
  }
#ifdef _DEBUG_L6474
 Serial.println("PWM set()\n");
#endif     

#ifdef _DEBUG_L6474
  uint16_t st;
  st=CmdGetParam(0,L6474_STATUS);
   snprintf(l6474StrOut, DEBUG_BUFFER_SIZE, "status#0 = %d \n",st);
   Serial.println(l6474StrOut);  
#endif     

  /* Standby-reset deactivation */
  ReleaseReset();

This produced the follwing on the Arduino "IDE" monitor

Enter begin()
PWM set()
status#0 = 0 
Stop->Acc: speed: 800 relPos: 1
Acc->Steady: speed: 1073 relativepos: 1599 

No callback is installed that could be clearing the error in response to error pin interrupt.

I've tested the 3 shield demo with 8V Vin, motors move ok. I reduce it until, at about 5v, it causes a UVLO condition, the motors stop and red D2 fault LED comes on.

I press the reset button on the Arduino; UVLO fault remains; D2 remains on, but CmdGetStatus() and CmdGetParam(0,L6474_STATUS); are still returning zero.

Maybe I'm making a careless mistake but it looks simple enough. Has this code been thoroughly tested ?

Michel-F commented 9 years ago

Hi J-Dunn, Just a quick answer, but normally the get status command (or the get param with the status register as parameter) should never return 0. Indeed, even if there is no error to report, the status register has some flags set to 1 by default (see the L6474 datasheet but for example, the UVLO flag is reset to 0 when the under voltage is detected else its value is 1). Sometimes, I also had some getstatus which returned 0 but these case were generally due to a bad SPI jumper configurations, L6474 without power supply or in reset state. This last case is also your case: you made a mistake by reading the status register before releasing the reset signal of the L6474. You should try this code:

case 1: pinMode(L6474_DIR_1_Pin, OUTPUT); pinMode(L6474_PWM_1_Pin, OUTPUT); PwmInit(0); default: ; }

ifdef _DEBUG_L6474

Serial.println("PWM set()\n");

endif

/* Standby-reset deactivation */ ReleaseReset();

ifdef _DEBUG_L6474

uint16_t st; st=CmdGetParam(0,L6474_STATUS); snprintf(l6474StrOut, DEBUG_BUFFER_SIZE, "status#0 = %d \n",st); Serial.println(l6474StrOut);

endif

J-Dunn commented 9 years ago

Thanks for your suggestions. I've been checking this with the oscilloscope and there is nothing happening on MISO, always low. Rest of the pins show credible patterns.

I started with your 3 motor demo which does move the motor but similarly did not produce correct status bytes. Since it was running that does not fit the chips being in reset.

I'm too tired to work on this now, I'll have a closer look tommorow.

Thanks.

J-Dunn commented 9 years ago

I had indeed put my debuggging output the wrong side of the ReleaseReset() call , thanks. I am now getting a credible status byte back from the single shield demo.

However, I have also noticed that your library is missing the wakeup delay for the logic cct when coming out of reset/standby state. Datasheet says tlogicwu can be a max of 45us. So to be in accord with the spec. a delay should be added. This should probably be added to ReleaseReset() funciton.

void L6474::ReleaseReset(void)
{ 
  digitalWrite(L6474_Reset_Pin, HIGH);
  WaitUs(45);  // max tlogicwu coming out of reset/standby condition
}