Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
M
Microstepper
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Projects
Microstepper
Commits
1c502780
Commit
1c502780
authored
Sep 21, 2021
by
Anders Wallin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ustepper script calculations
parent
f2f5cd50
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
199 additions
and
9 deletions
+199
-9
plot_ustep.py
scripts/plot_ustep.py
+46
-0
ustep.py
scripts/ustep.py
+98
-0
ustep_calc.py
scripts/ustep_calc.py
+55
-9
No files found.
scripts/plot_ustep.py
0 → 100644
View file @
1c502780
"""
This file is part of the Microstepper project
https://www.ohwr.org/project/microstepper
This simple script computes microstepper output frequency
given DDS frequency tuning words.
released under GPLv3 or later license.
Anders Wallin, 2019-2020
"""
import
matplotlib.pyplot
as
plt
import
numpy
import
ustep
# nominal F1
F1
=
112535015102874
F2
=
112589990683444
y
,
y18
=
ustep
.
y_out
(
F1
,
F2
)
print
(
[
"
%02
x"
%
x
for
x
in
ustep
.
split_hex
(
F1
)])
print
(
y18
)
yset
=
numpy
.
linspace
(
-
100
,
100
,
400
)
#print(yset)
y18s
=
[]
fs
=
[]
for
y
in
yset
:
ftw2
=
ustep
.
f2_from_y
(
y
,
F1
)
_
,
y18
=
ustep
.
y_out
(
F1
,
ftw2
)
y18s
.
append
(
y18
)
fs
.
append
(
ftw2
)
plt
.
figure
()
fs
=
numpy
.
array
(
fs
)
plt
.
plot
(
yset
,
yset
,
'r-'
,
label
=
'Ideal'
)
plt
.
plot
(
yset
,
y18s
,
'.'
,
label
=
'uStepper'
)
plt
.
plot
(
yset
,
y18s
-
yset
,
'm.'
,
label
=
'Error'
)
plt
.
xlabel
(
'set-point / y18'
)
plt
.
ylabel
(
'output / y18'
)
plt
.
legend
()
plt
.
grid
()
plt
.
show
()
scripts/ustep.py
0 → 100644
View file @
1c502780
"""
This file is part of the Microstepper project
https://www.ohwr.org/project/microstepper
Library for microstepper related functions
released under GPLv3 or later license.
Anders Wallin, 2019-2020
"""
import
bigfloat
import
numpy
import
requests
dds_clk
=
1.0e9
ftw_length
=
pow
(
2
,
48
)
# nominal F1, F2, for N_div=8, M_div=1024
# these FTWs give output closest to reference frequency, i.e. y approx= 0.
F1
=
112535015102874
F2
=
112589990683444
def
ftw_dds
(
f_hz
):
""" return AD9912 DDS Frequency tuning word, given desired frequency in Hz.
Assumes 1GHz SYSCLK
Only even FTWs possible in practice (i.e. LSB is allways zero)
"""
with
bigfloat
.
precision
(
200
):
a
=
bigfloat
.
BigFloat
.
exact
(
f_hz
)
b
=
bigfloat
.
BigFloat
.
exact
(
ftw_length
)
c
=
bigfloat
.
BigFloat
.
exact
(
dds_clk
)
ftw
=
a
*
b
/
c
ftwi
=
round_to_even
(
ftw
)
return
int
(
ftwi
)
def
hz_dds
(
ftw
):
""" return DDS output-frequency in Hz, given frequency tuning word
"""
return
dds_clk
*
ftw
/
ftw_length
def
round_to_even
(
f
):
""" AD9912 frequency tuning words are ALLWAYS even
i.e. the LSB is allways zero.
"""
return
round
(
f
/
2.
)
*
2
def
y_out
(
ftw1
,
ftw2
,
N_div
=
8.0
,
M_div
=
1024.0
):
""" given frequency tuning words, compute fractional frequency of microstepper
F_out / F_REF
"""
with
bigfloat
.
precision
(
200
):
F1term
=
bigfloat
.
BigFloat
.
exact
(
ftw1
/
4.0
)
F2term
=
bigfloat
.
BigFloat
.
exact
(
ftw2
/
(
N_div
*
M_div
))
Fsum
=
F1term
+
F2term
y
=
ftw_length
*
bigfloat
.
pow
(
10.0
*
(
Fsum
),
-
1.0
)
-
1.0
y18
=
y
*
bigfloat
.
BigFloat
.
exact
(
1e18
)
return
y
,
y18
def
f2_from_y
(
y18
,
ftw1
,
N_div
=
8.0
,
M_div
=
1024.0
):
""" given fractional frequency, compute frequency tuning word for DDS2
y = f_out/f_ref - 1.0
y=0 corresponds to f_out = f_ref
y18 input is in units of 1e-18
"""
with
bigfloat
.
precision
(
200
):
a
=
bigfloat
.
BigFloat
.
exact
(
pow
(
2
,
48
)
)
/
bigfloat
.
BigFloat
.
exact
(
10.0
)
y
=
bigfloat
.
BigFloat
.
exact
(
1.0
)
+
y18
/
bigfloat
.
BigFloat
.
exact
(
1e18
)
b
=
bigfloat
.
BigFloat
.
exact
(
1.0
)
/
y
c
=
bigfloat
.
BigFloat
.
exact
(
ftw1
)
/
bigfloat
.
BigFloat
.
exact
(
4.0
)
d
=
bigfloat
.
BigFloat
.
exact
(
N_div
*
M_div
)
ftw2
=
d
*
(
a
*
b
-
c
)
#print(ftw2)
#print(" y - 1 = %.3g" %(y-1.0))
#print(int(ftw2))
ftw2i
=
round_to_even
(
ftw2
)
return
int
(
ftw2i
)
def
set_DDS
(
ftw
,
DDS
=
0
,
IP
=
"192.168.1.18"
):
""" use HTTP to set DDS frequency to given frequency tuning word
DDS index can be 0 or 1
"""
hexs
=
split_hex
(
ftw
)
ftw_string
=
"
%02
x:
%02
x:
%02
x:
%02
x:
%02
x:
%02
x"
%
(
hexs
[
0
],
hexs
[
1
],
hexs
[
2
],
hexs
[
3
],
hexs
[
4
],
hexs
[
5
]
)
r
=
requests
.
get
(
'http://
%
s/DDS:
%
s:FTW:
%
s'
%
(
IP
,
DDS
,
ftw_string
))
def
split_hex
(
ftw
):
""" Split FTW into six 2-digit hex words
"""
mask
=
0x0000000000ff
out
=
[]
for
n
in
range
(
6
):
hexdigits
=
(
ftw
&
(
mask
<<
n
*
8
)
)
>>
n
*
8
#print("%x " % hexdigits)
out
.
append
(
hexdigits
)
return
out
scripts/ustep_calc.py
View file @
1c502780
...
...
@@ -14,15 +14,27 @@ import numpy
def
ftw_dds
(
f_hz
):
""" return AD9912 1GHz SYSCLK FTW
"""
return
numpy
.
round
(
f_hz
*
ftw_length
/
dds_clk
,
0
)
with
bigfloat
.
precision
(
200
):
a
=
bigfloat
.
BigFloat
.
exact
(
f_hz
)
b
=
bigfloat
.
BigFloat
.
exact
(
ftw_length
)
c
=
bigfloat
.
BigFloat
.
exact
(
dds_clk
)
ftw
=
a
*
b
/
c
ftwi
=
round_to_even
(
ftw
)
return
int
(
ftwi
)
def
hz_dds
(
ftw
):
""" return f_out [Hz]
"""
return
dds_clk
*
ftw
/
ftw_length
def
round_to_even
(
f
):
""" AD9912 frequency tuning words are ALLWAYS even
i.e. the LSB is allways zero.
"""
return
round
(
f
/
2.
)
*
2
def
y_out
(
ftw1
,
ftw2
,
N_div
=
4.0
,
M_div
=
1024.0
):
""" fractional frequency of microstepper
"""
given frequency tuning words, compute
fractional frequency of microstepper
F_out / F_REF
"""
with
bigfloat
.
precision
(
200
):
...
...
@@ -30,20 +42,46 @@ def y_out(ftw1, ftw2, N_div=4.0, M_div=1024.0):
F2term
=
bigfloat
.
BigFloat
.
exact
(
ftw2
/
(
N_div
*
M_div
))
Fsum
=
F1term
+
F2term
y
=
ftw_length
*
bigfloat
.
pow
(
10.0
*
(
Fsum
),
-
1.0
)
-
1.0
return
y
y18
=
y
*
bigfloat
.
BigFloat
.
exact
(
1e18
)
return
y
,
y18
def
f2_from_y
(
y18
,
ftw1
,
N_div
=
4.0
,
M_div
=
1024.0
):
""" given fractional frequency, compute frequency tuning word for DDS2
y = f_out/f_ref - 1.0
y=0 corresponds to f_out = f_ref
y18 input is in units of 1e-18
"""
with
bigfloat
.
precision
(
200
):
a
=
bigfloat
.
BigFloat
.
exact
(
pow
(
2
,
48
)
)
/
bigfloat
.
BigFloat
.
exact
(
10.0
)
y
=
bigfloat
.
BigFloat
.
exact
(
1.0
)
+
y18
/
bigfloat
.
BigFloat
.
exact
(
1e18
)
b
=
bigfloat
.
BigFloat
.
exact
(
1.0
)
/
y
c
=
bigfloat
.
BigFloat
.
exact
(
ftw1
)
/
bigfloat
.
BigFloat
.
exact
(
4.0
)
d
=
bigfloat
.
BigFloat
.
exact
(
N_div
*
M_div
)
ftw2
=
d
*
(
a
*
b
-
c
)
#print(ftw2)
#print(" y - 1 = %.3g" %(y-1.0))
#print(int(ftw2))
ftw2i
=
round_to_even
(
ftw2
)
return
int
(
ftw2i
)
dds_clk
=
1.0e9
ftw_length
=
pow
(
2
,
48
)
DDS2_nom
=
400e6
# nominal frequency of DDS
N_div
=
8
0
.0
# first divider 2/4/8
DDS2_nom
=
hz_dds
(
ftw_dds
(
400e6
)
)
# nominal frequency of DDS
N_div
=
8.0
# first divider 2/4/8
M_div
=
1024.0
# second divider 2**10 = 1024
IF
=
DDS2_nom
/
(
N_div
*
M_div
)
# 97656.25 Hz
print
(
"IF =
%.3
f Hz"
%
IF
)
print
(
"DDS2 nom = "
,
DDS2_nom
)
print
(
"IF2 =
%.3
f Hz"
%
IF
)
# nominally we get zero output frequency with these
# tuning-wrods:
F1
=
ftw_dds
(
400e6
-
4.0
*
IF
)
# DDS1
IF1
=
(
100e6
-
hz_dds
(
F1
)
/
4.0
)
F2
=
ftw_dds
(
N_div
*
M_div
*
IF1
)
# DDS2
F2approx
=
ftw_dds
(
N_div
*
M_div
*
IF1
)
# DDS2
print
(
"F1 "
,
F1
)
F2
=
f2_from_y
(
0
,
F1
,
N_div
=
N_div
,
M_div
=
M_div
)
print
(
"F2 approx = "
,
F2approx
)
print
(
"F2 = "
,
F2
)
#IF2 = hz_dds(F2)/(N_div*M_div)
#F1 = ftw_dds(400e6-4.0*IF2) # DDS1
...
...
@@ -63,7 +101,7 @@ ys =[]
for
delta
in
[
-
5
,
-
4
,
-
3
,
-
2
,
-
1
,
0
,
1
,
2
,
3
,
4
,
5
]:
delta
=
2
*
delta
F1x
=
F1
+
delta
y1
=
y_out
(
F1x
,
F2
,
N_div
=
N_div
)
y1
,
_
=
y_out
(
F1x
,
F2
,
N_div
=
N_div
)
ys
.
append
(
y1
)
print
(
"
%
d
\t
%
d
\t
%.3
g"
%
(
F1x
,
delta
,
y1
)
)
print
(
"y change due to 2 steps in FTW1:
%.2
g"
%
(
min
(
numpy
.
diff
(
ys
)))
)
...
...
@@ -75,10 +113,18 @@ ys =[]
for
delta
in
[
-
5
,
-
4
,
-
3
,
-
2
,
-
1
,
0
,
1
,
2
,
3
,
4
,
5
]:
delta
=
2
*
delta
F2x
=
F2
+
delta
y1
=
y_out
(
F1
,
F2x
,
N_div
=
N_div
)
y1
,
_
=
y_out
(
F1
,
F2x
,
N_div
=
N_div
)
ys
.
append
(
y1
)
print
(
"
%
d
\t
%
d
\t
%.3
g"
%
(
F2x
,
delta
,
y1
)
)
print
(
"y change due to 2 steps in FTW2:
%.3
g"
%
(
min
(
numpy
.
diff
(
ys
)))
)
print
(
40
*
"-"
)
y18
=
5678
F2
=
f2_from_y
(
y18
,
F1
,
N_div
=
N_div
,
M_div
=
M_div
)
print
(
"F2 2e-17= "
,
F2
)
yget
,
yget18
=
y_out
(
F1
,
F2
,
N_div
=
N_div
,
M_div
=
M_div
)
print
(
yget18
)
print
(
" y_out =
%.6
g"
%
yget
)
print
(
" y(set)-y_out =
%
d "
%
(
y18
-
yget
*
1e18
)
)
print
(
" y(set)-yget18 =
%.6
f "
%
(
y18
-
yget18
)
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment