Errors while Communicating with SPI Daisy Chain Devices

I found one more source of error in the system. It seems that some of the wire-to-wire power connectors are reliable. So the L6470’s are resetting constantly. Simply touching the cable during operation can cause it to disconnect. From one thing to another.

So is this a for fun project or something else? Even if this is just for fun, you might want to consider getting some appropriate test equipment. While you might eventually be successful without it, it will be a lot more fun with even a modicum of reasonable tools. At work I have a many thousands of dollars Agilent scope. At home, I have a used $200 Tek I got off of eBay. Usually the Tek and a (name that I can never spell, sounds like Sally) logic analyzer help me understand what is going on. If I was buying a scope today for personal use, I would get one of the Rigol ones that are about $400. While it is not as fast/accurate as the Agilent, it would do a great job for most things I would need. I would also get a logic analyzer. I have the old Logic 8 at home and a Pro 16 at work. I found the analog sampling of the Pro to be worthless. It would send the software on my high-end workstation computer out to lunch. Once I turned off the analog channels it worked much better. The Pro series have higher channel counts and selectable logic levels, which can come in handy, but I don’t believe I have needed more than 8 so far.

I don’t know how many hours you have spent on this or how much you value your time, but unless you value the learning more you might want to consider the scope.

1 Like

@ Frogmore - I’ve been dogging buying a scope for 6 years (which is about how long I’ve been working on this project). It’s not for fun; it’s very much something else. And yes, I value my time very much.

A scope is the minimum test equipment anyone working on electronics should have. You can actually buy a good scope brand new for a few hundred dollars now. The Rigol DS1054Z is a bargain and there is information on how to jump this from the 50Mhz that is comes with to 100Mhz.
Don’t waste your money on an old analogue one, get a new digital one as they allow you to capture the waveform.

2 Likes

@ Dave McLaughlin - Actually, I’ve been thinking about using a PC based usb scope. Since, I can buy more of them and capture data indefinitely during the operation of the system. I can even mount them on the machine to inspect both signal integrity and power consumption. Since I have a Windows Slate that’s sitting on my desk doing nothing, I can dedicate it to the scope(s). While I understand the argument for the Rigol, completely, given my data logger needs, wouldn’t a PC based scope be more suitable?

Love my DS1054Z. Highly recommend it.

1 Like

I was going to say stay away from USB scopes, but I did a quick search and found this http://www.eetimes.com/document.asp?doc_id=1326699
If EE Times says it’s time for a USB scope who am I to say no :slight_smile:

Beware, the software/UX of many of these leave a lot to desire. If you hook them up incorrectly, you can destroy the PC that is attached. They generally have pretty low sample rates, so aliasing can be an issue. On the plus side the display might be bigger.

Having said all that, I have a tiny “nano” scope, it’s even a copy of the official one. It worked great on a project where I needed a strip chart recorder for a very slowly moving signal. I wouldn’t use it for anything much above audio frequencies.

Having a standalone scope is really handy, but having something that can show you what is going on is indispensable. So, if you really want the USB kind, do some more research, read a lot reviews and see what people on http://www.eevblog.com have to say.

@ Frogmore - Having researched usb scopes, I can say that the main downside that I’ve found on all of them is that the software is crappy. How come Rigol can make good enough software for their bench scopes but no one else can for usb scopes? I’m even looking at those open source wanna be scopes. I figure it would be better to have them just capture the data and then plot the data with math software.

Having used a number of different types and models of scopes over the last 35 years, I would say there does not appear to be general agreement about what is good. Though many people have strong opinions :slight_smile:

Some of the concepts about what a scope needs to do are known, but finding the way the function is implemented on any particular model, even from the same manufacturer, can be a challenge. With the ubiquity of microcontrollers, many things are possible, but that doesn’t always make them a good idea. Making a good user experience is really hard, especially when user requirements and experiences vary.

I have never used one, but I have heard really good things about the Rigol line and the DS1054Z is the one I would buy, if I didn’t already have one and access to another one that costs 17 times as much.

As far as a logic analyzer goes. My expensive Keysight (previously known as Agilent, and HP before that) scope has a 16 channel one built in. I have never used it, probably because the screen is too small and I generally don’t work on highly mixed signal systems. But, I have used my Logic Pro 16 lots of times. But even it has some poor UI. It is nearly impossible to use with touch. You have to use a mouse with a wheel or you will pull your hair out. It also doesn’t let you get the display of particular lines larger, even if you only need to use 4 channels, the traces are sized to fit many more on the screen.

Well you guys won. I caved and purchased the Rigol. +1 for Peer pressure. :clap:

3 Likes

you won’t be sorry. Its honestly the most awesome scope for the money. And you’ve got 30 hours of full featured access including deep memory, and I’m sure your searching will tell you whether that’s possible to extend.

1 Like

Well Well Well… the SPI decode (in the 30 hours of extended features) only supports 32 bits of decoding (width of the frame). But my project needs 80 bits of decoding. This means I can’t diagnose any of the drivers past the 4th one. -1 for Peer pressure :frowning:

Soooo what did you finally end up using for the clock rate. I literally have been going through the same exact issues (except with only one L6470). I find the only useable clock rate is 1 kHz which seems ridiculously low compared to the values I see others using for the same dSpin set up. If I try to change the clock rage any higher, my registers won’t set.

I have a theory it may be the charge pump oscillator capacitor I initially used. About to retry. From what I read, if the charge pump capacitor is not pumping at the correct rate, the phases in the stepper motor will not reach high enough current / have it applied long enough to finish the step before it switches to the next phase, resulting in stalled vibration. That is the only possible thing I can think of. Using a G30.

Oh yea, I was wrong about the SPI decode option. I was just using it wrong. Apologies! It actually works now, and properly.

@hwalker_MIWV, I’ve managed to get reliable control from the single stepper just fine. I believe that it was at 1000 Khz. Another thing that we have to consider when using SPI to control the drivers is that the signal wires should all be the same length. @Dave_McLaughlin could talk more about this.

How close and length should they be and whats the max length? I just built the set up again and can’t get the registers to all set now.

Actually now I have the registers set but all my motor does is vibrate. This happened last set up and when I disconnected the charge pump oscillator it started moving, tons of gitter, but still moving.

You may need to increase the acc , dec and run power values

I had them at 50 and more. The registries wont let me set certain values for some reason. Also my SPI communication just started screwing up out of nowhere.

Post the code you’re using to initilize the device.

Ok just a second. I turned off all the power and restarted it, the registries began setting again. Motor is still frozen vibrating though. Does phase A1 connect to A1 on the motor and A2 to A2 or does it connect A1 to B1? I am a little confused on powering the phases. I know if you touch the leads together and if their is low resistance they are on the same phase. But I am not sure what I am supposed to gather from that. Going to grab the code off the other computer now.

using System;
using Microsoft.SPOT;
using GHI.Pins;
using GHI.Processor;
using GHI.Utilities;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation.Media;
using System.Threading;

using Microsoft.SPOT.Presentation;
using Drivers;

public class Program
{
 
 
        private static InputPort stbyPort;
        private static InputPort busyPort;
        private static dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct;
        private static dSpin stepperDriver;
        private static Random _rnd;


   public static void Main()
   {
  
  
        
            

            try
            {
             _rnd = new Random();
            dSPIN_RegsStruct = new dSPIN_RegsStruct_TypeDef();
            UInt32 dSPIN_rx_data = 0;
 
            Debug.EnableGCMessages(false);
            busyPort = new InputPort(G30.Gpio.PA15, false, Port.ResistorMode.Disabled);
            stbyPort = new InputPort(G30.Gpio.PC13, false, Port.ResistorMode.PullDown);

            SPI.Configuration _spiConfig = new SPI.Configuration(G30.Gpio.PB7,
                false,
                2,
                2,
                false,
                true,
                1000,
                SPI.SPI_module.SPI1);
               // Cpu.Pin.GPIO_Pin2,false);
            SPI spiPort = new SPI(_spiConfig);
     


  
            /* Structure initialization by default values, in order to avoid blank records */
            dSpin.dSPIN_Regs_Struct_Reset(ref dSPIN_RegsStruct);
 
            stepperDriver = new dSpin(spiPort, busyPort,null);
 
            stepperDriver.dSPIN_Reset_Device();
 
            /* Acceleration rate settings to 466 steps/s2, range 14.55 to 59590 steps/s2 */
            dSPIN_RegsStruct.ACC = Macro.AccDecStepsTopar(100);  // 466
            /* Deceleration rate settings to 466 steps/s2, range 14.55 to 59590 steps/s2 */
            dSPIN_RegsStruct.DEC = Macro.AccDecStepsTopar(200);  // 466
            /* Maximum speed settings to 488 steps/s, range 15.25 to 15610 steps/s */
            dSPIN_RegsStruct.MAX_SPEED = Macro.MaxSpdStepsToPar(200);  // 488
            /* Minimum speed settings to 0 steps/s, range 0 to 976.3 steps/s */
            dSPIN_RegsStruct.MIN_SPEED = Macro.MinSpdStepsToPar(100);
            /* Full step speed settings 252 steps/s, range 7.63 to 15625 steps/s */
            dSPIN_RegsStruct.FS_SPD = Macro.FSSpdStepsToPar(200);   // 252
 
            //The duty cycle values control power to the motor. If the motor is not running as expected
            //it may be because it it underpowered.
 
            /* Hold duty cycle (torque) settings to 10%, range 0 to 99.6% */
            dSPIN_RegsStruct.KVAL_HOLD = Macro.KvalPercToPar(10);
            /* Run duty cycle (torque) settings to 10%, range 0 to 99.6% */
            dSPIN_RegsStruct.KVAL_RUN = Macro.KvalPercToPar(40);
            /* Acceleration duty cycle (torque) settings to 10%, range 0 to 99.6% */
            dSPIN_RegsStruct.KVAL_ACC = Macro.KvalPercToPar(40);
            /* Deceleration duty cycle (torque) settings to 10%, range 0 to 99.6% */
            dSPIN_RegsStruct.KVAL_DEC = Macro.KvalPercToPar(40);
 
            //end duty cycles
 
            /* Intersect speed settings for BEMF compensation to 200 steps/s, range 0 to 3906 steps/s */
            dSPIN_RegsStruct.INT_SPD = Macro.IntSpdStepsToPar(0);
            /* BEMF start slope settings for BEMF compensation to 0.038% step/s, range 0 to 0.4% s/step */
            dSPIN_RegsStruct.ST_SLP = Macro.BEMFSlopPercToPar(0.03);
            /* BEMF final acc slope settings for BEMF compensation to 0.063% step/s, range 0 to 0.4% s/step */
            dSPIN_RegsStruct.FN_SLP_ACC = Macro.BEMFSlopPercToPar(0.063);
            /* BEMF final dec slope settings for BEMF compensation to 0.063% step/s, range 0 to 0.4% s/step */
            dSPIN_RegsStruct.FN_SLP_DEC = Macro.BEMFSlopPercToPar(0.063);
            /* Thermal compensation param settings to 1, range 1 to 1.46875 */
            dSPIN_RegsStruct.K_THERM = Macro.KThermToPar(1);
 
            /* Overcurrent threshold settings to 1500mA */
            dSPIN_RegsStruct.OCD_TH = (byte)dSPIN_OCD_TH_TypeDef.dSPIN_OCD_TH_1875mA; //my power supply can't handle more than 1000mA
 
            /* Stall threshold settings to 1000mA, range 31.25 to 4000mA */
            dSPIN_RegsStruct.STALL_TH = Macro.StallThToPar(2000);
            /* Step mode settings to 128 microsteps */
            dSPIN_RegsStruct.STEP_MODE = (byte)dSPIN_STEP_SEL_TypeDef.dSPIN_STEP_SEL_1;
            /* Alarm settings - all alarms enabled */
            dSPIN_RegsStruct.ALARM_EN = (byte)(dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_OVERCURRENT | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_THERMAL_SHUTDOWN
                | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_THERMAL_WARNING | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_UNDER_VOLTAGE | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_STALL_DET_A
                | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_STALL_DET_B | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_SW_TURN_ON | dSPIN_ALARM_EN_TypeDef.dSPIN_ALARM_EN_WRONG_NPERF_CMD);
            /* Internal oscillator, 2MHz OSCOUT clock, supply voltage compensation disabled, *
             * overcurrent shutdown enabled, slew-rate = 290 V/us, PWM frequency = 15.6kHz   */
            dSPIN_RegsStruct.CONFIG = ((UInt16)dSPIN_CONFIG_OSC_MGMT_TypeDef.dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ) |
                ((UInt16)dSPIN_CONFIG_SW_MODE_TypeDef.dSPIN_CONFIG_SW_HARD_STOP) |
                ((UInt16)dSPIN_CONFIG_EN_VSCOMP_TypeDef.dSPIN_CONFIG_VS_COMP_DISABLE) |
                ((UInt16)dSPIN_CONFIG_OC_SD_TypeDef.dSPIN_CONFIG_OC_SD_ENABLE) |
                ((UInt16)dSPIN_CONFIG_POW_SR_TypeDef.dSPIN_CONFIG_SR_290V_us) |
                ((UInt16)dSPIN_CONFIG_F_PWM_INT_TypeDef.dSPIN_CONFIG_PWM_DIV_2) |
                ((UInt16)dSPIN_CONFIG_F_PWM_DEC_TypeDef.dSPIN_CONFIG_PWM_MUL_1);
 
            /* Program all dSPIN registers */
            stepperDriver.dSPIN_Registers_Set(ref dSPIN_RegsStruct);
 
 
            /* Send dSPIN command change hold duty cycle to 0.5% */
            stepperDriver.dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_HOLD, Macro.KvalPercToPar(1)); //Kval_Perc_to_Par(0.5)
 
            /* Send dSPIN command change run duty cycle to 5% */
            stepperDriver.dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_RUN, Macro.KvalPercToPar(5)); //Kval_Perc_to_Par(5);
 
 
            /* Perform SoftStop commmand */
            stepperDriver.dSPIN_Soft_Stop();
 
          uint totalSteps = new uint();
            for (; ; )
            {


                UInt32 stepps = (uint)(128 * _rnd.Next(200));
                totalSteps += stepps;
 
 
                stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.FWD, stepps);
            //    stepperDriver.dSPIN_Get_Status();
                while (stepperDriver.dSPIN_Busy_SW() == 1)
                {
                    Thread.Sleep(1);
                }
                //stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.REV, stepps);
 
                //while (stepperDriver.dSPIN_Busy_SW() == 1)
                //{
                  //  Thread.Sleep(1);
                //}
            }
         
            }
            catch (Exception ex)
            { ex.ToString(); }