We are still finishing the propforth release, so peter will hold off sending us samples till the next release is out. Sal is planning a set of CNC extensions as the next step in the project, so this is definitely still on the list.
I have only just been getting back to this stepper board and running some tests on a 91mm NEMA34 (34HY1801) motor @24V. It seems with the mass of an drive roller attached I can run this at up to 2400rpm. I have a particular job where I need to ramp from normal process speed up to as high a speed as possible for half a second or so.
Just wondering what kind of speeds are achievable with other steppers and motors? Has anyone done any tests in this regard?
I've got a 60mm diameter roller on the end of it which drives a 300mm long belt and there's another NEMA34 on the other side and normally the motors are running at the exact same speed. The winding is 1.2 ohms and rated at 2.8A but the average measured running current total for each motor is normally around 0.5A.
I have done a lot of tests now and have concluded that with a nominal 24DC supply that I can run this motor reliably up to 2000 RPM and I have pushed it to over 2500 RPM but it's that weak a feather could stop it. There are a lot of registers in the L6470 that aren't explained very well but I think I have enough of a handle on it for now. Here's a short video if you are interested.
Love the sound... you can hear how smooth it is. Yes this would be a very nice addition to my bot. NEMA34s really don't like to go fast. On the low end they have really great torque but they drop like cliffs as the RPMs increase. I'll bet you could get a NEMA 23 that had more torque at the higher RPMs.
I'll be anxious to see these come out. My bot is limited to 8 microsteps just because the controller can't provide more PPS while also figuring accel. With these I'm free to let the chip do the work and let the controller handle the I2C command interface without concern for stepping on the toes of the pulse generation.
I have four NEMA34 for the next rig I build. Will these be OK if we want to go fast to move to a new position, but only need torque when we want to move slow (ie with the tool engaged)?
I think I remember something about dynamically adjusting voltage or current depending on speed or load. Doe the L6470 support this?
Sal said it shouldn't be a problem for the software, I think he's building this into the stepper functions.
Prof: There are a lot of things that the chip does automatically although it does rely on what you load into the registers but it can also be run under external control quite easily. There are a couple of ways of doing this and my module brings out the discrete step clock pin also. So it's possible to setup the direction, current, etc over SPI and then issue individual step clocks from the Prop if you really want.
BTW, since I'm back in the stepper saddle I will organize to send off the sample modules to you as well as to others who have been waiting
Wow! I've pushed my NEMA34 up to 3400 RPM and beyond. The L6470 can be set to switch to full-step mode automatically above a set threshold and so I am running the motor in full-step mode at this speed. Sure is fast for a big motor. I will try a smaller motor next to see how fast I can push it.
Wow! I've pushed my NEMA34 up to 3400 RPM and beyond. The L6470 can be set to switch to full-step mode automatically above a set threshold and so I am running the motor in full-step mode at this speed. Sure is fast for a big motor. I will try a smaller motor next to see how fast I can push it.
For the last 24 hours, I have been reexamining some of my old schematics and reviewing the characteristics of both the L6470 and the L6208. During this time, I have been weighing the value of speed (full/half step) versus accuracy (microstep), and then it dawned on me about this threshold. As you know, the L6208 is intended for half/full step operation, whereas the L6470 is intended for microstepping operation, however I am now contemplating putting D/A converters on VREF_A and VREF_B of the L6208 to achieve somewhat of a programmable resolution (microstepping thru full stepping). I would assume this is similar to what you are referring to on the L6470.
I'm familiar with the L6208 and other variants etc and I don't think that there is anything that they can do that the L6470 can't. Look, if you don't use all the features and just run the L6470 in dumb full/half step mode with an external step clock you are still far better off IMO than using the L6208 in this dumb mode. Once you start using any degree of current control or micro-stepping then you are already in front as it's all built-in, you don't even need external current sense resistors. BTW, the stepping modes can be set from full-step, half-step etc to 128 microsteps. These chips run as cool as cucumbers.
Anyway, I found a bug with this auto full-step switching as it appears it doesn't actually switch to full-step but another microstep mode instead. However I am awaiting some feedback from ST about this.
I was contemplating ordering some L6470 samples from ST, I just have not done that yet. As for now, I already have several of the L6208s laying around, and a lot of the layout has been done, so I am pretty much just finishing up what I have and I will experiment a little. The main reason I am doing this now is so that I have a real world example for my exposure box thread. I am sure I will order some of the L6470s and experiment with those as well in the future. I just don't have the time available to start it all from scratch.
Bruce, that reminds me that I was going to send you a couple of samples, so sorry about the delay since I haven't been playing with these devices for quite a few weeks a I get distracted. I will send two control boards off to you tomorrow.
There is no rush. I have not had the time to devote to the PCB driller as I intended, and I don't imagine that I will get to it for at least a couple more weeks.
Didn't you see the photos, the tiny chip .... on the tiny pcb ..... on the BIG BAD stepper motor. You know that I just use a dedicated toaster oven for making up my prototypes and with a little solder paste all this tiny SMD stuff is a pushover.
Since I'm back on this thread I have included some updated Forth code. Most of this code is for interacting with the steppers and viewing results.
fl
[ifdef L6470.fth
forget L6470.fth
]
: L6470.fth ;
{
*************************************************************
L6470H Microstepper motion controller chip demo
March 2012 Peter Jakacki
Hardware: Propeller CPU (P1109 PuppySolo CPU module)
L6470 Stepper controller (PSM6470 MicroStepper module)
P1121 Motor Controller motherboard
Software: PropForth 4.6
Handles 3A rms per winding. Uses SPI interface.
Define port allocations
Using Prop's EPROM I2C as clock and data to the L6470
Pullups on SDO (from L6470), BUSY, and FLAG as well as
precautionary pullups on CS and pulldown on RST
*************************************************************
}
decimal
28 constant .SCL
29 constant .SDA
0 constant .SDI \ data from L6470
1 constant .BUSY \ busy flag - pullup with 10K
2 constant .CS1 \ Select master chip
3 constant .CS2 \ slave chip (or daisy chained)
4 constant .STCK1 \ step clock (optional, not used)
5 constant .STCK2
6 constant .FLAG \ pullup with 10K
7 constant .RST \ Chip standby/reset - pulled down with 10K
15 constant .SENSOR2
14 constant .SENSOR1 \ NORMALLY LOW
0 constant OFF
-1 constant ON
variable response
variable unit
hex
: SELECT unit ! ;
: CS unit @ ;
: MASTER .CS1 SELECT ;
: SLAVE .CS2 SELECT ;
: TXRAW
_sclh
CS pinout CS pinlo
80 8 0
do
_scll
response @ 2* .SDI px? 1 and or response !
2dup and if _sdah else _sdal then
_sclh
2/
loop
2drop
CS pinin ;
: WAIT begin .BUSY px? until ;
: TX WAIT TXRAW ;
\ Made direction a variable to be added to the command so that it could
\ be "set and forget", no need to specify each time.
\
variable dir
: FWD 1 dir C! ;
: REV 0 dir C! ;
: +DIR dir C@ or ; \ adds direction into the command
decimal
\ this little table holds the bit size of each register so that read and writes of longs can be automatically formatted
variable regsize -4 allot
00 c, 22 c, 09 c, 22 c,
20 c, 12 c, 12 c, 10 c,
13 c, 08 c, 08 c, 08 c,
08 c, 14 c, 08 c, 08 c,
08 c, 04 c, 05 c, 04 c,
07 c, 10 c, 08 c, 08 c,
16 c, 16 c, 00 c, 00 c,
hex
\ Writing to a register is a SetParam command with the register address as the PARAM field
\ Up to 3 bytes of data are needed but unfortunately the byte order varies depending upon the register's size
\ So a lookup is performed in the regsize table and the data arranged accordingly
: REG! \ ( dat reg -- )
0 response !
dup 1F and regsize + C@ \ determine bit size of the register ( dat reg size )
dup 9 < if drop else \ 8 bits or less ? ( dat reg )
10 > if TXRAW dup 10 rshift then \ 16 bits or more ? then send: reg bits16..24
TXRAW dup 8 rshift then \ 9 to 15 bits send: cmd bits8..15
TXRAW TXRAW \ this is either CMD+DAT or trailing
;
\ Modify register address into a GetParam command and send null data while the TXRAW routine reads the response
: REG@ \ ( reg -- data )
0 swap 20 or REG! \ issue corresponding bytes
response @ \ pickup response assembled by TXRAW
;
hex
\ Getstatus does not wait if the L6470 is busy but performs a non-invasive status read
: GetStatus \ ( -- status ) \ if no response is received (no chip) then return with 0 as status
D0 TXRAW 0 TXRAW 0 TXRAW 0 TXRAW response @ 8 rshift dup FFFFFF = if drop 0 then ;
\
: CMD \ ( dat cmd -- )
TX dup 10 rshift TX dup 8 rshift TX ff and TX
GetStatus drop ;
\ : SYNCH 0 0 CMD ;
\ L6470 application commands - named similar as per programming manual
: NOP 0 TX ; \ also useful to cause application to wait until controller is ready
: RUN \ ( speed -- )
50 +DIR CMD ;
: MOVE \ ( steps -- )
40 +DIR CMD ;
: GoTo \ ( position -- ) Go to an absolute position
60 CMD ;
: GoToDIR \ ( position -- )
68 +DIR CMD ;
: GoUntil \ ( speed act -- )
3 lshift 82 or +DIR CMD ;
: ReleaseSW \ ( act -- )
3 lshift 92 or +DIR CMD ;
: GoHome 70 TX ;
: GoMark 78 TX ;
: ResetPos D8 TX ;
: ResetDevice C0 TX ;
: SoftStop B0 TX ; \ Stop after deceleration
: HardStop B8 TX ; \ Stop immediately
: SoftHiZ A0 TX ; \ Decelerate before bridge disconnection
: HardHiZ A8 TX ; \ Immediate bridge disconnection
\ Register names - mainly for convenience and readability
\ Keep these names to less than 8 characters to maintain an order NFA
01 constant @POS
02 constant @EPOS
03 constant @MARK
04 constant @SPEED \ current speed
05 constant @ACC \ acceleration
06 constant @DEC \ deceleration
07 constant @MAX \ max speed
08 constant @MIN \ min speed
09 constant @HOLD \ hold current
0A constant @RUN \ run current * adjust this for slower speeds - while running
0B constant @STACC \ accel starting current
0C constant @STDEC \ dec staring current
0D constant @INTSPD \ Intersect speed
0E constant @ACCSS \ Acceleration start slope
0F constant @ACCFS \ Acceleration final slope
10 constant @DECDS \ Deceleration final slope
11 constant @THERM \ Thermal compensation factor
12 constant @ADC \ 5 bits of ADC reading supply voltage
13 constant @OCD \ overcurrent threshold
14 constant @STALL \ stall threshold
15 constant @FSSPD \ full step speed threshold
16 constant @STEPMD \ controls number of microsteps or none
17 constant @ALARMS \ alarm mask
18 constant @CONFIG \ PWM and clock control etc
19 constant @STATUS
\ Some console friendly aliases
: STOP SoftStop GetStatus drop ; \ Stop and also read the status to clear any errors
: HALT B8 TXRAW ; \ Stop immediately, override any operation
: DISC SoftHiZ ; \ Disconnect the bridge - also needed before certain commands can be written
: HOME GoHome ;
: GO GoTo ;
hex
: CONFIG! STOP DISC @CONFIG REG! ;
: PWMDIV \ ( 1..7 --)
1- 0 max 07 and 6 min 0D lshift @CONFIG REG@ 1FFF and or CONFIG! ;
: PWMDEC \ ( 0..7 -- ) multiply the PWM freq from 0.625 to 2 in 0.125 increments
7 and 0A lshift @CONFIG REG@ E3FF and or CONFIG! ;
: SLEW \ ( 0..3 -- ) adjust the slew rate as 180,180,290,530
3 and @CONFIG REG@ FCFF and or CONFIG! ;
: VSCOMP \ ( on/off -- )
if 20 else 0 then @CONFIG REG@ 20 invert and or CONFIG! ;
decimal
\ Initialization table values to suit motor and application
\ Multiple tables can be setup for various motors and the table pointer
\ passed to the INIT routine if necessary. Just this one at present.
\ This is a 34HY1801 Nema34
\
variable inits -4 allot \ variables points to start of table
decimal \ some motor properties in same table but not part of L6470 registers
\ first 5 values are not loaded into registers but represent motor constants
200 w, \ steps/rev
231 w, \ rpmcon
0 w,
0 w,
0 w,
\ REG 5
400 w, \ Acceleration
400 w, \ Deceleration
452 w, \ Maximum speed (for sm7)
0 w, \ Minimum
20 w, \ Holding current
32 w, \ Run current
64 w, \ Acceleration starting current
32 w, \ Deceleration starting current
1032 w, \ Intersect speed
128 w, \ Start slope
19 w, \ Acceleration final slope
64 w, \ Deceleration final slope
0 w, \ Thermal compensation
0 w, \ ADC (read only)
15 w, \ Over-current threshold
127 w, \ Stall Threshold (set to max)
550 w, \ Full step speed (changes from microstep)
7 w, \ Step mode
hex
FF w, \ Alarm enables
1E80 w, \ Config \ 2e88
0 w, 0 w, 0 w, \ reserved
: INIT@ 2* inits + W@ ;
hex
: !REGS HALT DISC 19 5 do i INIT@ i REG! loop ;
variable status
: INIT
.RST dup pinout dup pinlo pinhi \ Hardware reset - pulse line low
_sclo _sclh _sdao \ Use I2C lines as outputs for clock and data in (L6470)
.CS2 dup pinhi pinout \ chip selects
.CS1 dup pinhi pinout
SLAVE !REGS GetStatus status 2+ W!
MASTER !REGS GetStatus status W!
;
1
hex
: STEPS \ ( steps -- )
@STEPMD REG@ lshift 3FFFFF min MOVE ;
: TURNS \ ( turns -- )
0 INIT@ * STEPS ;
: READY? \ ( -- rdyflg )
GetStatus 2 and ;
: BUSY? \ ( -- bsyflg )
READY? 0= ;
decimal
: RPM \ ( rpm -- ) Run motor at speed to match rpms
1 INIT@ * RUN ;
hex
\ Rough conversion from ADC reading to voltage (pretty close)
: VOLTS @ADC REG@ 9 * 2/ 2/ 2/ ;
\ Simply for console diagnostics to see the status register conditions
: ShowStatus
dup if
dup 8000 and if cr ." Step Clock Mode" then
dup 4000 and 0= if cr ." Step Loss B" then
dup 2000 and 0= if cr ." Step Loss A" then
dup 1000 and 0= if cr ." Over Current" then
dup 0800 and 0= if cr ." Thermal Shutdown" then
dup 0400 and 0= if cr ." Thermal Warning" then
dup 0200 and 0= if cr ." Under voltage" then
dup 0100 and if cr ." Wrong command" then
dup 80 and if cr ." Command not performed" then
\
cr ." Speed = " @SPEED REG@ 1 INIT@ / . ." RPM"
dup 60 and 5 rshift
dup 0= if ." stopped" then
dup 1 = if ." accelerating" then
dup 2 = if ." decelerating" then
3 = if ." constant" then
dup 10 and if ." forward" else ." reverse" then
dup 8 and if cr ." Switch Event" then
dup 4 and if cr ." Switch Closed" then
dup 2 and 0= if cr ." Busy" then
dup 1 and if cr ." Bridge disconnected" then
cr ." Steps/full step = " @STEPMD REG@ 1 swap lshift .
cr ." Input Voltage = " VOLTS decimal . ." V"
else
." - No device "
then
drop
;
\ ********************* DEMO & DEBUG **********************
\
\ Short diagnostic functions which simplify keyboard entry
\ List Registers ( in current number base )
\ Use the name for the register as provided in the compiled constant names (tricky)
' @POS _forthpfa>nfa constant regstr
: .NAME 1- 4 lshift regstr + dup C@ 0F and swap 1+ over .str 0A swap - spaces ;
hex
: LR
." REG NAME MASTER SLAVE DEFAULT "
\ 01: 0020571A 00000000 000000E7
1A 1 do cr i .byte 3A emit space i .NAME
MASTER i REG@ .long space SLAVE i REG@ .long
4 spaces i INIT@ .long loop cr MASTER ;
\ List the status of the chips
: L \ List the status of the chip(s) for diagnostics
\ busy and flag pins are common
ina COG@ dup 2 and 0= if ." =busy " then 40 and 0= if ." =flag " then
SLAVE GetStatus dup if cr ." SLAVE " dup ShowStatus then drop
MASTER GetStatus dup if cr ." MASTER " dup ShowStatus then drop
cr
;
\ Stop both motors
: S SLAVE STOP MASTER STOP ;
\ set step mode 0..7 (up the max on full step)
: SM DISC dup @STEPMD REG! if 1C0 else 2FF then @MAX REG! ;
\ write config register
: CFG DISC @CONFIG REG! ;
\ Set RUN current
: RC @RUN REG! ; \ SET RUN CURRENT
\ Some extra test functions
decimal
\ spin the motor back and forth at max speed
: DEMO
begin FWD 2000 RPM 3000 ms REV 2000 RPM 3000 ms key? until STOP ;
Peter, when you apply solder paste for the Q44 are you saying it's easy? I bought three smt Props and solder paste but I hesitate because I assume I'll get it wrong a few times.
I have threatened to do a video to show how easy it is, so I will see about doing one now. However you will find that rather than being ultra-careful I just run a bead of paste across the middle of the pads so that it spans the pads. When I place the Prop or the L6470 I smudge it in a little then when it goes into the preheated toaster oven set at max it takes around 3 minutes for the solder to start to reflow. I leave mine in for about 4 minutes and sometimes 5 if it looks like it needs it as the toaster elements are a bit rough with temperature regulation. However I have never really had any real problems and sometimes I might have to clean up a few bridges either with the end of a flat iron tip or if that doesn't work then a splodge of flux then the iron again. Very rarely do I need the solder wick. Rather than placing the pcb on the rack in the oven I place it on aluminum foil thats been folded up into about four or more layers to act as a tray. When you remove this tray from the oven using a flat piece of metal as a pizza shovel then you find that the foil cools down very quickly plus it also cushions the pcbs a bit from vibration. I have been using the solid tray that comes with the oven lately and as long as I'm careful not to knock it then it seems to work well too.
The pcbs you see in the photos in this thread have been made this way.
There's probably lot's of little things I forget to mention so a video should clear it up a bit.
Since I'm back on this thread I have included some updated Forth code. Most of this code is for interacting with the steppers and viewing results.
Great stuff, thanks for sharing!
Can I ask questions about your code? Mostly little stuff to establish common formatting and use conventions. Forth code is easy, the thought process behind it is what throws me.
Is there a coding standard you follow, I would like to look at what being used as a "Propforth coding standard" starts to evolve.
For example, what does the period represent? That the label is a prop I/O pin? Usually I see period prefixed to a label to indicate that a value will displayed on the screen (like period pops and displays the top stack item), have you seen that before?
Also fetch and store words: I see that you append @ to labels for constants, is there some generalization we can make when we see these in your code?
My thought is that at some point we might do a group review of code that we wish to add to the extensions or change in the kernel, so we make thing more clear and easier to follow. With out getting too cumbersome, I'd like to start on a "style guide" if we can make some consensus. (Sal continues to write code "stream of consciousness" until we establish a standard to which we can compare).
I wouldn't take any of my stuff as any kind of standard, it just works for me. The periods that are prepended to the constants are a bit of a carry over from assembler I think where I couldn't do much with symbol names but just enough to give me a hint that it is a pin constant although it could be confused with the Forth print function. However my variables are lower case to separate them from actual application code which is either upper-case or CamelCase as I do_detest_the_annoying_underscore. There are many times when I have a variable called for instance "sample" and the word that uses the variable with the same name except capitalized in some fashion such as "SAMPLE". Long names are descriptive and "nice" I guess but being more succinct is far more desirable and also a lot easier to remember and to type into the terminal. That's also why I have aliases for some words to make it easier to type with one hand while the other holds a probe etc.
Now as for the @ symbol prepended to the constants well that's to signify an address of some kind like saying "AT this address" so @ACC is the address of the acceleration register. The @ after a word is always read as FETCH of course. I'm also not adverse to placing a long line of code if it makes sense to.
I aim for readability (at least for me) but stack manipulation gets in the way of that but then again, where would Forth be without the stack? Interestingly I normally implement a separate stack for the loop parameters in my Forths rather than using the return stack. That way I can factor out code and still reference the loop parameters without touching the return stack (always a recipe for disaster I find).
Forth on the Prop is very useful but also very cumbersome compared to more conventional processors so I don't mind if things aren't all that standard, plus I never did like any of the Forth standards formulated by committees, they are too full of compromises and/or they try to put everyone's ingredients into the same pot. I also can't get over the fact that although Forth's real strength is in real-time and embedded systems the focus in the standards seem to be bloated and PC-centric.
I'll save talk of "coding standards" until we start peer reviewing extensions to add to the main archive, if that ever comes about.
Not to get too much further off topic (I could move this to another thread if you wish) is your third stack along the lines of vannorman and koopman? http://www.ece.cmu.edu/~koopman/forth/rochester_90b.pdf
Sal and I talked about this for goofy stuff like float and software multitasking, and Sal advised to "not go nuts" until we go the kernel working.
I am using 'Trinamic' chipset (TMC428 & TMC249).
And I want to design a new 'Microstepper'.
The L6470 specifications are very good.
And the price and size of this solution is a 'winner'.
Before purchasing the evaluation board, I am wondering if this chip can also control a basic 'brush DC Motor'
With the internal H bridge, it could easily drive 2 brush DC Motor or 1 super brush DC Motor.
But in the specification I cannot find this information.
If you already have the evaluation board, Could you tell me if this feature is possible ?
I don't use brush DC motor very often, but it could be a plus.
While the L6470 is IMO a very good microstepper controller and driver I doubt very much that it would be a good solution for DC motors. The only way to directly control what the outputs will do is to write directly to the electrical position register EL_POS and even then I don't think it's a great solution. So it's no wonder you didn't find it in the specification because it's not specified or designed to wash dishes or drive DC motors. But all that depends upon what degree of "plus" you are after. I will probably try some DC motors just for the fun of it and who knows???
I did not expect the L6470 to drive brush DC motors.
But it was a possibility.
I noticed the L6460 chip.
It is a dual solution Microstepper/brush DC motors.
But there is a 1/16 limitation on the Microstepper side.
Anyway I also found a Texas Instrument solution:
DRV8412 (or32) + F28035 microcontroller.
It is a chipset solution and I need to add some external components to get a current feedback.
The price of this solution is x2 the one with L6470 (the pcb size is also bigger).
Hi ,
Been a while since this tread has had activity - has there been any further developments on the task of demonstrating the use of l6470s in a cnc capacity ?
thanks
chaz
Here's some updated code I use for this chip on my P1121 dual stepper pcb with the PuppySolo. This is loaded just like any other PropForth extension by pasting the text into a terminal (at 230400 baud) and then backing up the compiled code with the "saveforth" command. After that I just load my simple application on top of that without having to touch the driver again. This is more than a driver though as it is setup for diagnostics and formatting results.
I have a couple of P1121 sets here that I am sending Tubular and possibly a set to Prof Braino so they can play with these on their CNC machines and report back.
EDIT: I can setup a unit hooked-up to a couple of motors running PropForth and connect via Bluetooth back to an XPORT module (or maybe a Spinneret) that would be accessible via TELNET and also have a webcam running. While viewing the webcam stream someone could TELNET and start typing commands and even enter code if they want. If you want to telnet the best Windows terminal to use IMO is TeraTerm (via Sourceforge). Let me know if you are interested and I will set it all up over the weekend, maybe with something interesting attached to the motors. What's the best way of getting the TELNET data so others can see it? I guess maybe just plant a monitor in the webcam view?
fl
[ifdef L6470
forget L6470
]
: L6470 ." L6470 MicroStepper V1.1 120602" ;
{
L6470 Microstepper driver module - load in before application code and issue "saveforth" to lock into PropForth
2012 Peter Jakacki
Using: PropForth 5.2 (beta)
Compiled including diagnostics etc takes around 3.3kB
Implemented on PuppySolo - working configuraton uses two L6470 modules
.BUSY and .FLAG lines are monitored (and used) but are superfluous as status register can be read
Step clock STCK lines could be useful for CNC modes where steps have to be synchronized
.RST is probably not needed either but is a quick way to reset all stepper drivers.
}
decimal
0 constant .MISO \ MISO data from L6470 - multiple outputs are commoned with 220R in each output.
1 constant .BUSY \ busy flag - pullup with 10K
2 constant .CS1 \ Select master chip
3 constant .CS2 \ slave chip (or daisy chained)
4 constant .STCK1 \ step clock (optional, not used here)
5 constant .STCK2
6 constant .FLAG \ pullup with 10K
7 constant .RST \ Chip standby/reset - pulled down with 10K
28 constant .SCK \ SCL is shared with SCK
29 constant .MOSI \ SDA is shared with MOSI
0 constant OFF \ I like to be able to say OFF VALVE and sensible stuff like that
-1 constant ON
variable response \ holds the last response
wvariable unit \ remember which unit was selected (MASTER or SLAVE)
hex
: !PIN dup pinhi pinout ;
: SELECT unit W! ;
: CS unit W@ ;
: MASTER .CS1 SELECT ;
: SLAVE .CS2 SELECT ;
\ Transmit serial data to L6470 - couold benefit from some PASM eventually
: TXRAW \ ( data -- ) \ Sequence: CS LO + 8x(SCL LO + RD + WR + SCL HI) + CS HI 80us/bit
_sclh
CS pinout CS pinlo
80 8 0 \ Start with mask = MSB = 80 and loop 8 times from 0 to 7
do
_scll \ clock low then read MISO data
response L@ 2* .MISO px? 1 and or response L!
\ dup both data and mask and test bit and set MOSI
2dup and if _sdah else _sdal then
_sclh \ clock the data into the L6470 on low-to-high
2/ \ shift mask right
loop
2drop \ discard the data and mask (yeah, us Forthers get down and dirty and do our own garbage collection!)
CS pinin \ Let the CS float high (allowing other cogs to take control perhaps)
;
\ This could just do a readstatus register instead (using TXRAW)
: WAIT begin .BUSY px? until ;
: TX WAIT TXRAW ;
\ Made direction a variable to be added to the command so that it could
\ be "set and forget", no need to specify each time.
\
wvariable dir
: FWD 1 dir C! ;
: REV 0 dir C! ;
: +DIR dir C@ or ; \ adds direction into the command
decimal
\ this little table holds the bit size of each register so that read and writes of longs can be automatically formatted
variable regsize -4 allot
00 c, 22 c, 09 c, 22 c,
20 c, 12 c, 12 c, 10 c,
13 c, 08 c, 08 c, 08 c,
08 c, 14 c, 08 c, 08 c,
08 c, 04 c, 05 c, 04 c,
07 c, 10 c, 08 c, 08 c,
16 c, 16 c, 00 c, 00 c,
hex
\ Writing to a register is a SetParam command with the register address as the PARAM field
\ Up to 3 bytes of data are needed but unfortunately the byte order varies depending upon the register's size
\ So a lookup is performed in the regsize table and the data arranged accordingly
: REG! \ ( dat reg -- )
0 response L!
dup 1F and regsize + C@ \ determine bit size of the register ( dat reg size )
dup 9 < if drop else \ 8 bits or less ? ( dat reg )
10 > if TXRAW dup 10 rshift then \ 16 bits or more ? then send: reg bits16..24
TXRAW dup 8 rshift then \ 9 to 15 bits send: cmd bits8..15
TXRAW TXRAW \ this is either CMD+DAT or trailing
;
\ Modify register address into a GetParam command and send null data while the TXRAW routine reads the response
: REG@ \ ( reg -- data )
0 swap 20 or REG! \ issue corresponding bytes
response L@ \ pickup response assembled by TXRAW
;
hex
\ Getstatus does not wait if the L6470 is busy but performs a non-invasive status read
: GetStatus \ ( -- status ) \ if no response is received (no chip) then return with 0 as status
D0 TXRAW 0 TXRAW 0 TXRAW 0 TXRAW response L@ 8 rshift dup FFFFFF = if drop 0 then ;
\ Sends a command to the L6470
: CMD \ ( dat cmd -- ) \ Send "cmd" then 3 bytes of data high byte first
TX dup 10 rshift TX dup 8 rshift TX FF and TX
GetStatus drop ;
\ L6470 application commands - named similar as per programming manual
: NOP 0 TX ; \ also useful to cause application to wait until controller is ready
: RUN \ ( speed -- )
50 +DIR CMD ;
\ Manual step clock command
: STEPCK 58 +DIR TX ;
\ Issue step clocks - make sure L6470 is in STEPCK mode
: XSTEP .STCK1 dup pinhi pinlo ;
: XSTEPS swap 0 do XSTEP dup 0 do loop loop drop ;
: MOVE \ ( steps -- ) \ automatically accels and decels
40 +DIR CMD ;
: GoTo \ ( position -- ) Go to an absolute position
60 CMD ;
: GoToDIR \ ( position -- )
68 +DIR CMD ;
: GoUntil \ ( speed act -- ) \ not used here as it uses a homing switch
3 lshift 82 or +DIR CMD ;
: ReleaseSW \ ( act -- )
3 lshift 92 or +DIR CMD ;
: GoHome 70 TX ;
: GoMark 78 TX ;
: ResetPos D8 TX ;
: ResetDevice C0 TX ;
: SoftStop B0 TX ; \ Stop after deceleration
: HardStop B8 TX ; \ Stop immediately
: SoftHiZ A0 TX ; \ Decelerate before bridge disconnection
: HardHiZ A8 TX ; \ Immediate bridge disconnection
\ Register names - mainly for convenience and readability
\ Keep these names to less than 8 characters to maintain an indexed NFA used by LR for diagnostics
00 constant @REGS
01 constant @POS
02 constant @EPOS
03 constant @MARK
04 constant @SPEED \ current speed
05 constant @ACC \ acceleration
06 constant @DEC \ deceleration
07 constant @MAX \ max speed
08 constant @MIN \ min speed
09 constant @HOLD \ hold current
0A constant @RUN \ run current * adjust this for slower speeds - while running
0B constant @STACC \ accel starting current
0C constant @STDEC \ dec staring current
0D constant @INTSPD \ Intersect speed
0E constant @STSLP \ start slope - BEMF compensation curve
0F constant @ACCFS \ Acceleration final slope
10 constant @DECDS \ Deceleration final slope
11 constant @THERM \ Thermal compensation factor
12 constant @ADC \ 5 bits of ADC reading supply voltage
13 constant @OCD \ overcurrent threshold
14 constant @STALL \ stall threshold
15 constant @FSSPD \ full step speed threshold
16 constant @STEPMD \ controls number of microsteps or none
17 constant @ALARMS \ alarm mask
18 constant @CONFIG \ PWM and clock control etc
19 constant @STATUS
decimal
\ Initialization table values to suit motor and application
\ Multiple tables can be setup for various motors and the table pointer
\ passed to the INIT routine if necessary. Just this one at present.
\ This is a 34HY1801 Nema34 in general-purpose mode
\
variable inits -4 allot \ variables points to start of table
decimal \ some motor properties in same table but not part of L6470 registers
\ first 5 values are not loaded into registers but represent motor constants
200 w, \ steps/rev
13334 w, \ rpmmul
60 w, \ rpmdiv
0 w,
0 w,
\ REG 5
600 w, \ @ACC Acceleration
400 w, \ @DEC Deceleration
452 w, \ @MAX Maximum speed (for sm7)
0 w, \ @MIN Minimum
20 w, \ @HOLD Holding current
50 w, \ @RUN Run current
100 w, \ @STACC Acceleration starting current
50 w, \ @STDEC Deceleration starting current
1032 w, \ @INTSPD Intersect speed
80 w, \ @STSLP Start slope
40 w, \ @ACCFS Acceleration final slope
\ register 10
64 w, \ @DECFS Deceleration final slope
0 w, \ @THERM Thermal compensation
0 w, \ @ADC ADC (read only)
15 w, \ @OCD Over-current threshold
127 w, \ @STALL Stall Threshold (set to max)
550 w, \ @FSSPD Full step speed (changes from microstep)
7 w, \ @STEPMD Step mode
hex
FF w, \ @ALARMS Alarm enables
\ 18
1EA0 w, \ @CONFIG Config \ 2e88
0 w, 0 w, 0 w, \ reserved
variable @inits \ pointer to init table
: INIT@ 2* @inits L@ + W@ ;
hex
\ Some console friendly aliases
: STOP SoftStop GetStatus drop ; \ Stop and also read the status to clear any errors
: HALT B8 TXRAW ; \ Stop immediately, override any operation, don't wait
: DISC SoftHiZ ; \ Disconnect the bridge - also needed before certain commands can be written
: HOME GoHome ;
: GO GoTo ;
: CONFIG! STOP DISC @CONFIG REG! ;
: PWMDIV \ ( 1..7 --)
1- 0 max 07 and 6 min 0D lshift @CONFIG REG@ 1FFF and or CONFIG! ;
: PWMDEC \ ( 0..7 -- ) multiply the PWM freq from 0.625 to 2 in 0.125 increments
7 and 0A lshift @CONFIG REG@ E3FF and or CONFIG! ;
: SLEW \ ( 0..3 -- ) adjust the slew rate as 180,180,290,530
3 and @CONFIG REG@ FCFF and or CONFIG! ;
: VSCOMP \ ( on/off -- )
if 20 else 0 then @CONFIG REG@ 20 invert and or CONFIG! ;
: LSCOMP \ ( rpm -- ) 300RPM = 4194
d292 min STOP d8388 d600 */ d4096 + @MIN REG! ;
\ Initialize L6470 registers using init table values
: !REGS HALT DISC 19 5 do i INIT@ i REG! loop ;
variable status
\ Initialize L6470 chips using parameter table address supplied (0=default)
: !L6470 \ ( tbl -- ) Initialize the L6470 stepper chip using the table supplied ( or default = 0)
dup 0= if drop inits then @inits L!
.RST dup pinout dup pinlo pinhi \ Hardware reset - pulse line low
_sclo _sclh _sdao \ Use I2C lines as outputs for clock and data in (L6470)
.CS2 !PIN \ chip selects
.CS1 !PIN
.STCK1 !PIN
.STCK2 !PIN
SLAVE !REGS GetStatus status 2+ W!
MASTER !REGS GetStatus status W!
;
\ Move motor n steps in last selected direction
: STEPS \ ( steps -- )
@STEPMD REG@ lshift h3FFFFF min MOVE ;
\ Using the steps/turn data in the init table, step the motor n turns
: TURNS \ ( turns -- )
0 INIT@ * STEPS ;
: READY? \ ( -- rdyflg )
GetStatus 2 and ;
: BUSY? \ ( -- bsyflg )
READY? 0= ;
: RPM \ ( rpm -- ) Run motor at speed to match rpms
d13334 d60 */ RUN ;
\ ********************* DIAGNOSTICS **************************
hex
\ Rough conversion from ADC reading to voltage (pretty close)
: VOLTS @ADC REG@ 9 * 2/ 2/ 2/ ;
\ Little extension to help analyse the bit in a number (TOS) then select next bit
variable bit
: BIT? dup bit L@ and bit L@ 2/ bit L! ;
\ Simply for console diagnostics to see the status register conditions
: ShowStatus
dup if 8000 bit L!
BIT? if cr ." Step Clock Mode" then
BIT? 0= if cr ." Step Loss B" then
BIT? 0= if cr ." Step Loss A" then
BIT? 0= if cr ." Over Current" then
BIT? 0= if cr ." Thermal Shutdown" then
BIT? 0= if cr ." Thermal Warning" then
BIT? 0= if cr ." Under voltage" then
BIT? if cr ." Wrong command" then
BIT? if cr ." Command not performed" then
\
cr ." Speed = " @SPEED REG@ 2 INIT@ 1 INIT@ */ . ." RPM"
dup 60 and 5 rshift
dup 0= if ." stopped" then
dup 1 = if ." accelerating" then
dup 2 = if ." decelerating" then
3 = if ." constant" then
\ 10 bit L!
BIT? if ." forward" else ." reverse" then
BIT? if cr ." Switch Event" then
BIT? if cr ." Switch Closed" then
BIT? 0= if cr ." Busy" then
BIT? if cr ." Bridge disconnected" then
cr ." Steps/full step = " @STEPMD REG@ 1 swap lshift .
cr ." Input Voltage = " VOLTS decimal . ." V"
else
." - No device "
then
drop
;
\ ********************* DEMO & DEBUG **********************
\
\ Short diagnostic functions which simplify keyboard entry - especially via bluetooth smartphones !
\ List Registers ( in current number base )
\ Use the name for the register as provided in the compiled constant names (tricky)
' @POS _forthpfa>nfa constant regstr
: .NAME 1- 4 lshift regstr + dup C@ 0F and swap 1+ over .str 0A swap - spaces ;
hex
\ List names and contents of registers of both MASTER and SLAVE as well as their default values
: LR
." REG NAME MASTER SLAVE DEFAULT "
\ 01: 0020571A 00000000 000000E7
1A 1 do cr i .byte 3A emit space i .NAME
MASTER i REG@ .long space SLAVE i REG@ .long
4 spaces i INIT@ .long loop cr MASTER ;
\ List the status of the chips
: L \ List the status of the chip(s) for diagnostics
\ busy and flag pins are common
ina COG@ dup 2 and 0= if ." =busy " then 40 and 0= if ." =flag " then
SLAVE GetStatus dup if cr ." --------SLAVE-------- " dup ShowStatus then drop
cr MASTER GetStatus dup if cr ." --------MASTER-------- " dup ShowStatus then drop
cr ;
\ Stop both motors - very useful when testing
: S CS SLAVE STOP MASTER STOP SELECT ;
\ set step mode 0..7 (up the max on full step) example: 4 SM ( sets step mode to 4 = 16 )
: SM DISC dup @STEPMD REG! if 1C0 else 2FF then @MAX REG! ;
\ write config register as in: 2EA8 CFG!
: CFG! DISC @CONFIG REG! ;
\ Set RUN current as in: 30 RC
: RC @RUN REG! ; \ SET RUN CURRENT
That's awesome Peter, look forward to having a play soon. If/when you need them back just let me know.
Regarding the webcam demo, for a long time I've wanted to do something similar. I think it would really work well even just with a monitor in the corner. I have a canon vc-c1 camera with pan, tilt and 26x zoom, autofocus, great picture (its the same optics used in camcorders I think). Puts out composite video, and is controlled using RS232 stream. If this is any use I'm happy to send it up. Or I could set it up down here with the modules you send down.
Agreed re TeraTerm it's an outstanding little program especially at high baud rates. Hard to believe its been around for as long as it has, still keeps working great.
Hi Tubular, I will send you two sets so you can work with 4 axis control and if you hook them up via telnet and webcam that would be great too. I will still have a go at setting my end up though as it will be running PropForth so it will be very easy for anyone to start to make things happen from the first few seconds, just type away. I will tie in the webcam to a webpage that has some instructions and examples and links etc.
Anyone have any ideas how best to echo a telnet session onto the same webpage? The fallback is setting up a monitor in the webcam view.
I have a couple of P1121 sets here that I am sending Tubular and possibly a set to Prof Braino so they can play with these on their CNC machines and report back.
I'd be happy to do some work on these. If you send out a second pair, I will forward them to Sal.
Since I've been using these chips I thought I'd give the forum some feedback. There seems to be a lack of documentation in regard to interaction of the many parameters so this can be a little challenging sometimes because when you think you know what you are doing it doesn't work. Anyway for you CNC guys there is no reason why you can't use the chips in "manual" step clock mode as the chip has a lot of fine features and is amazingly small for what it does. This is a "cool" chip, you've seen that the only heatsinking I've been using is the thermal vias to the copper on the opposite side of the pcb.
I've only just recently been using them in this manual mode where I issue the step clock pulses and all other parameters are done over SPI and I have been very impressed with the results. Now I find that ST have released the L6474 which is a dumbed down version in the same package, same pinout etc and half the price almost. The difference with the L6474 is that it "only" does 16 microsteps but it also has a separate DIR pin in place of the SW pin so you can set it up via SPI and just use these two pins most of the time. Since my SPI routines are fast I'm finding it's no problem to set the direction and current via SPI and just use the step clock.
I have posted code here and also on my Tachyon pages.
Oh, and for anyone who might be waiting on some of these modules sorry but please give me a nudge, I've been way too distracted to catch-up and ship these modules off. I do have plenty of stock so if anyone wants to purchase them I am happy to sell the L6470 modules to forum members for $29 USD each + $10 airmail.
Comments
Just wondering what kind of speeds are achievable with other steppers and motors? Has anyone done any tests in this regard?
That said a DOL started 2 pole induction motor would hit 2900 rpm pretty quickly, but I assume you need accurate positioning too.
What kind of drive roller diameter? What kind of power is that stepper, 60 watts or so?
I'll be anxious to see these come out. My bot is limited to 8 microsteps just because the controller can't provide more PPS while also figuring accel. With these I'm free to let the chip do the work and let the controller handle the I2C command interface without concern for stepping on the toes of the pulse generation.
I'm over here, patiently waiting (drums fingers!)
I think I remember something about dynamically adjusting voltage or current depending on speed or load. Doe the L6470 support this?
Sal said it shouldn't be a problem for the software, I think he's building this into the stepper functions.
BTW, since I'm back in the stepper saddle I will organize to send off the sample modules to you as well as to others who have been waiting
For the last 24 hours, I have been reexamining some of my old schematics and reviewing the characteristics of both the L6470 and the L6208. During this time, I have been weighing the value of speed (full/half step) versus accuracy (microstep), and then it dawned on me about this threshold. As you know, the L6208 is intended for half/full step operation, whereas the L6470 is intended for microstepping operation, however I am now contemplating putting D/A converters on VREF_A and VREF_B of the L6208 to achieve somewhat of a programmable resolution (microstepping thru full stepping). I would assume this is similar to what you are referring to on the L6470.
Bruce
Anyway, I found a bug with this auto full-step switching as it appears it doesn't actually switch to full-step but another microstep mode instead. However I am awaiting some feedback from ST about this.
I was contemplating ordering some L6470 samples from ST, I just have not done that yet. As for now, I already have several of the L6208s laying around, and a lot of the layout has been done, so I am pretty much just finishing up what I have and I will experiment a little. The main reason I am doing this now is so that I have a real world example for my exposure box thread. I am sure I will order some of the L6470s and experiment with those as well in the future. I just don't have the time available to start it all from scratch.
I am sure the L6470 is a much better chip.
Bruce
There is no rush. I have not had the time to devote to the PCB driller as I intended, and I don't imagine that I will get to it for at least a couple more weeks.
Bruce
I just received three of the L6470HTR. Talk about small, these things are tiny How do you manage to work with them? WOW
Since I'm back on this thread I have included some updated Forth code. Most of this code is for interacting with the steppers and viewing results.
The pcbs you see in the photos in this thread have been made this way.
There's probably lot's of little things I forget to mention so a video should clear it up a bit.
Great stuff, thanks for sharing!
Can I ask questions about your code? Mostly little stuff to establish common formatting and use conventions. Forth code is easy, the thought process behind it is what throws me.
Is there a coding standard you follow, I would like to look at what being used as a "Propforth coding standard" starts to evolve.
For example, what does the period represent? That the label is a prop I/O pin? Usually I see period prefixed to a label to indicate that a value will displayed on the screen (like period pops and displays the top stack item), have you seen that before?
Also fetch and store words: I see that you append @ to labels for constants, is there some generalization we can make when we see these in your code?
My thought is that at some point we might do a group review of code that we wish to add to the extensions or change in the kernel, so we make thing more clear and easier to follow. With out getting too cumbersome, I'd like to start on a "style guide" if we can make some consensus. (Sal continues to write code "stream of consciousness" until we establish a standard to which we can compare).
Thanks!
Now as for the @ symbol prepended to the constants well that's to signify an address of some kind like saying "AT this address" so @ACC is the address of the acceleration register. The @ after a word is always read as FETCH of course. I'm also not adverse to placing a long line of code if it makes sense to.
I aim for readability (at least for me) but stack manipulation gets in the way of that but then again, where would Forth be without the stack? Interestingly I normally implement a separate stack for the loop parameters in my Forths rather than using the return stack. That way I can factor out code and still reference the loop parameters without touching the return stack (always a recipe for disaster I find).
Forth on the Prop is very useful but also very cumbersome compared to more conventional processors so I don't mind if things aren't all that standard, plus I never did like any of the Forth standards formulated by committees, they are too full of compromises and/or they try to put everyone's ingredients into the same pot. I also can't get over the fact that although Forth's real strength is in real-time and embedded systems the focus in the standards seem to be bloated and PC-centric.
Not to get too much further off topic (I could move this to another thread if you wish) is your third stack along the lines of vannorman and koopman?
http://www.ece.cmu.edu/~koopman/forth/rochester_90b.pdf
Sal and I talked about this for goofy stuff like float and software multitasking, and Sal advised to "not go nuts" until we go the kernel working.
I am using 'Trinamic' chipset (TMC428 & TMC249).
And I want to design a new 'Microstepper'.
The L6470 specifications are very good.
And the price and size of this solution is a 'winner'.
Before purchasing the evaluation board, I am wondering if this chip can also control a basic 'brush DC Motor'
With the internal H bridge, it could easily drive 2 brush DC Motor or 1 super brush DC Motor.
But in the specification I cannot find this information.
If you already have the evaluation board, Could you tell me if this feature is possible ?
I don't use brush DC motor very often, but it could be a plus.
Regards,
dli
I did not expect the L6470 to drive brush DC motors.
But it was a possibility.
I noticed the L6460 chip.
It is a dual solution Microstepper/brush DC motors.
But there is a 1/16 limitation on the Microstepper side.
Anyway I also found a Texas Instrument solution:
DRV8412 (or32) + F28035 microcontroller.
It is a chipset solution and I need to add some external components to get a current feedback.
The price of this solution is x2 the one with L6470 (the pcb size is also bigger).
Regards.
dli
Been a while since this tread has had activity - has there been any further developments on the task of demonstrating the use of l6470s in a cnc capacity ?
thanks
chaz
I have a couple of P1121 sets here that I am sending Tubular and possibly a set to Prof Braino so they can play with these on their CNC machines and report back.
EDIT: I can setup a unit hooked-up to a couple of motors running PropForth and connect via Bluetooth back to an XPORT module (or maybe a Spinneret) that would be accessible via TELNET and also have a webcam running. While viewing the webcam stream someone could TELNET and start typing commands and even enter code if they want. If you want to telnet the best Windows terminal to use IMO is TeraTerm (via Sourceforge). Let me know if you are interested and I will set it all up over the weekend, maybe with something interesting attached to the motors. What's the best way of getting the TELNET data so others can see it? I guess maybe just plant a monitor in the webcam view?
Regarding the webcam demo, for a long time I've wanted to do something similar. I think it would really work well even just with a monitor in the corner. I have a canon vc-c1 camera with pan, tilt and 26x zoom, autofocus, great picture (its the same optics used in camcorders I think). Puts out composite video, and is controlled using RS232 stream. If this is any use I'm happy to send it up. Or I could set it up down here with the modules you send down.
Agreed re TeraTerm it's an outstanding little program especially at high baud rates. Hard to believe its been around for as long as it has, still keeps working great.
Anyone have any ideas how best to echo a telnet session onto the same webpage? The fallback is setting up a monitor in the webcam view.
I'd be happy to do some work on these. If you send out a second pair, I will forward them to Sal.
I've only just recently been using them in this manual mode where I issue the step clock pulses and all other parameters are done over SPI and I have been very impressed with the results. Now I find that ST have released the L6474 which is a dumbed down version in the same package, same pinout etc and half the price almost. The difference with the L6474 is that it "only" does 16 microsteps but it also has a separate DIR pin in place of the SW pin so you can set it up via SPI and just use these two pins most of the time. Since my SPI routines are fast I'm finding it's no problem to set the direction and current via SPI and just use the step clock.
I have posted code here and also on my Tachyon pages.
Oh, and for anyone who might be waiting on some of these modules sorry but please give me a nudge, I've been way too distracted to catch-up and ship these modules off. I do have plenty of stock so if anyone wants to purchase them I am happy to sell the L6470 modules to forum members for $29 USD each + $10 airmail.