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
c6539738
Commit
c6539738
authored
Sep 17, 2021
by
Anders Wallin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial work on http-interface
parent
4a633829
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
332 additions
and
11 deletions
+332
-11
dds_sw.ino
dds_sw/dds_sw.ino
+13
-6
ddslib.h
dds_sw/ddslib.h
+6
-2
httpd.h
dds_sw/httpd.h
+286
-0
ad9912_frequency.py
scripts/ad9912_frequency.py
+27
-3
No files found.
dds_sw/dds_sw.ino
View file @
c6539738
...
...
@@ -32,6 +32,7 @@
#include "ddslib.h"
#include "plllib.h"
#include "printf_wrapper.h"
#include "httpd.h" // web-server for controlling DDS-board
// SPI pin definitions
// using MKR ZERO with IO-board
...
...
@@ -42,21 +43,23 @@ const int SPI_CSB_DDSB = 3; //D3
const
int
SPI_CSB_PLL
=
4
;
//D4
// DDS-objects
AD9912
::
DDS
ddsA
(
SPI_SDIO
,
SPI_CSB_DDSA
,
SPI_SCLK
);
AD9912
::
DDS
ddsB
(
SPI_SDIO
,
SPI_CSB_DDSB
,
SPI_SCLK
);
AD9912
::
DDS
ddsA
(
SPI_SDIO
,
SPI_CSB_DDSA
,
SPI_SCLK
,
0
);
AD9912
::
DDS
ddsB
(
SPI_SDIO
,
SPI_CSB_DDSB
,
SPI_SCLK
,
1
);
// PLL-object
ADF4350
::
PLL
pll
(
SPI_SDIO
,
SPI_CSB_PLL
,
SPI_SCLK
);
// Webserver
HTTPD
::
httpd
*
webserver
=
new
HTTPD
::
httpd
(
&
ddsA
,
&
ddsB
);
void
setup
()
{
// put your setup code here, to run once:
Serial
.
begin
(
9600
);
delay
(
1000
);
Serial
.
print
(
"initializing.
\n
"
);
delay
(
2000
);
pll
.
preset1
();
// 10MHz input, 1 GHz DDS clock
delay
(
1000
);
delay
(
200
);
delay
(
100
);
delay
(
100
0
);
ddsA
.
reset
();
delay
(
100
);
ddsB
.
reset
();
...
...
@@ -108,11 +111,15 @@ void setup() {
ddsB
.
get_frequency
(
fr
);
delay
(
20
);
serial_printf
(
"fr = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
\n
"
,
fr
[
5
],
fr
[
4
],
fr
[
3
],
fr
[
2
],
fr
[
1
],
fr
[
0
]
);
delay
(
1000
);
webserver
->
init
();
delay
(
1000
);
Serial
.
print
(
"ready.
\n
"
);
}
void
loop
()
{
// put your main code here, to run repeatedly:
webserver
->
available
();
}
dds_sw/ddslib.h
View file @
c6539738
...
...
@@ -19,13 +19,16 @@ class DDS {
AW 2014-01-02
*/
public
:
DDS
(
int8_t
SDIO
,
int8_t
CSB
,
int8_t
SCLK
)
{
DDS
(
int8_t
SDIO
,
int8_t
CSB
,
int8_t
SCLK
,
int
id
)
{
spi
=
new
SPIBitBang
(
SDIO
,
CSB
,
SCLK
);
_id
=
id
;
};
~
DDS
()
{
delete
spi
;
}
int
get_id
()
{
return
_id
;
}
// read the part ID
// should return 0x1902 = 6402 (decimal)
int8_t
read_id
()
{
...
...
@@ -115,6 +118,7 @@ public:
private
:
SPIBitBang
*
spi
;
int8_t
ftw
[
6
];
int
_id
;
};
}
// end namespace
...
...
dds_sw/httpd.h
0 → 100644
View file @
c6539738
/*
* Arduino code for microstepper-project DDS-board
* AW2021-09, see https://ohwr.org/project/microstepper
*
*/
#ifndef __HTTPD_H__
#define __HTTPD_H__
/*
Web Server
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
This functionality inspired by Mini-Circuits rf-switch, which respons to:
requests.get("http://%s/SP6T%s:STATE:%d" % (ip, switch, state))
Based on work with rf-mux Ethernet control, see https://ohwr.org/project/rf-mux-8ch
*/
#include <SPI.h>
#include <Ethernet.h>
#include "ddslib.h"
namespace
HTTPD
{
// 90:A2:DA:AF:99:48
// MAC address generated by https://ssl.crox.net/arduinomac/
// see http://blog.crox.net/archives/91-MAC-generator.html
byte
mac
[
6
]
=
{
0x90
,
0xA2
,
0xDA
,
0xAF
,
0x99
,
0x48
};
#define FIXED_IP // define this to use a fixed IP
// #define DHCP_IP // to use DHCP, comment out line above and activate this line
// if FIXED_IP, use this address
IPAddress
ip
(
192
,
168
,
1
,
18
);
//IPAddress ip(192, 168, 3, 30);
//IPAddress ip(130, 188, 45, 253);
class
httpd
{
public
:
httpd
(
AD9912
::
DDS
*
ddsA
,
AD9912
::
DDS
*
ddsB
){
server
=
new
EthernetServer
(
80
);
// (port 80 is default for HTTP):
_ddsA
=
ddsA
;
_ddsB
=
ddsB
;
}
~
httpd
(){
delete
server
;
}
void
init
()
{
// start the Ethernet connection and the server:
#ifdef FIXED_IP
Ethernet
.
begin
(
mac
,
ip
);
// fixed IP
#endif
#ifdef DHCP_IP
Serial
.
println
(
"DHCP..."
);
int
dhcp_result
=
Ethernet
.
begin
(
mac
);
// DHCP result
Serial
.
print
(
"DHCP success? "
);
Serial
.
println
(
dhcp_result
);
#endif
server
->
begin
();
Serial
.
print
(
"MUX is at IP: "
);
Serial
.
println
(
Ethernet
.
localIP
());
//_m1->init();
//_m2->init();
}
void
available
()
{
// listen for incoming clients
EthernetClient
client
=
server
->
available
();
if
(
client
)
{
//Serial.println("new client");
// an http request ends with a blank line
boolean
currentLineIsBlank
=
true
;
while
(
client
.
connected
())
{
if
(
client
.
available
())
{
char
c
=
client
.
read
();
_httpRequest
+=
c
;
// Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if
(
c
==
'\n'
&&
currentLineIsBlank
)
{
// send a standard http response header
_httpRequest
.
toUpperCase
();
//Serial.print("_httpRequest: ");
//Serial.println( _httpRequest);
if
(
_httpRequest
.
indexOf
(
"GET / "
)
>=
0
)
{
// show only state, don't adjust anything
client
.
println
(
"HTTP/1.1 200 OK"
);
client
.
println
(
"Content-Type: text/html"
);
client
.
println
(
"Connection: close"
);
// the connection will be closed after completion of the response
//client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client
.
println
();
client
.
println
(
"<!DOCTYPE HTML>"
);
client
.
println
(
"<html>"
);
//client.println("Index page");
print_state
(
&
client
);
client
.
println
(
"</html>"
);
}
else
if
(
_httpRequest
.
indexOf
(
"GET /DDS"
)
>=
0
){
// parse command, then show state
// parse command
parse_command
();
client
.
println
(
"HTTP/1.1 200 OK"
);
client
.
println
(
"Content-Type: text/html"
);
client
.
println
(
"Connection: close"
);
// the connection will be closed after completion of the response
//client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client
.
println
();
client
.
println
(
"<!DOCTYPE HTML>"
);
client
.
println
(
"<html>"
);
print_state
(
&
client
);
client
.
println
(
"</html>"
);
}
_httpRequest
=
""
;
break
;
// request done- break out of while(connected)
}
if
(
c
==
'\n'
)
{
// you're starting a new line
currentLineIsBlank
=
true
;
}
else
if
(
c
!=
'\r'
)
{
// you've gotten a character on the current line
currentLineIsBlank
=
false
;
}
}
}
// give the web browser time to receive the data
delay
(
1
);
// close the connection:
client
.
stop
();
//Serial.println("client disconnected");
}
}
// end available()
#define DELIMETERS " :/" // split the httpRequest with these delimeters
void
parse_command
()
{
char
*
strings
[
10
];
// DDS:1:FTW:00:11:22:33:44:55 four tokens
char
*
ptr
=
NULL
;
byte
index
=
0
;
char
buf
[
_httpRequest
.
length
()
+
1
];
_httpRequest
.
toCharArray
(
buf
,
_httpRequest
.
length
());
//Serial.println("strtok() %s", buf);
ptr
=
strtok
(
buf
,
DELIMETERS
);
while
(
ptr
!=
NULL
)
{
strings
[
index
]
=
ptr
;
index
++
;
ptr
=
strtok
(
NULL
,
DELIMETERS
);
// takes a list of delimiters
if
(
index
>
9
)
// stop parsing string when we found what we want
break
;
}
// printout for debug
/*
for(int n = 0; n < index; n++) {
Serial.print("Token ");
Serial.print(n);
Serial.print(" ");
Serial.println(strings[n]);
}
*/
// URL request: http://192.168.1.18/DDS:0:FTW:00:11:22:33:44:55
// Token 0 GET
// Token 1 DDS
// Token 2 0
// Token 3 FTW
// Token 4 00
// Token 5 11
// Token 6 22
// Token 7 33
// Token 8 44
// Token 9 55
// 48-bit tuning word split into 6 hex numbers, each 8 bits
if
(
strcmp
(
strings
[
0
],
"GET"
)
==
0
)
{
if
(
strcmp
(
strings
[
1
],
"DDS"
)
==
0
)
{
AD9912
::
DDS
*
dds
;
uint8_t
state
;
if
(
strcmp
(
strings
[
2
],
"0"
)
==
0
)
{
dds
=
_ddsA
;
}
else
if
(
strcmp
(
strings
[
2
],
"1"
)
==
0
)
{
dds
=
_ddsB
;
}
else
{
return
;
}
if
(
strcmp
(
strings
[
3
],
"FTW"
)
==
0
)
{
//Serial.println("command received");
//Serial.print("MUX ");
//Serial.print(mux->get_id());
int8_t
f
[
6
];
f
[
0
]
=
(
int8_t
)
strtol
(
strings
[
4
],
NULL
,
16
);
f
[
1
]
=
(
int8_t
)
strtol
(
strings
[
5
],
NULL
,
16
);
f
[
2
]
=
(
int8_t
)
strtol
(
strings
[
6
],
NULL
,
16
);
f
[
3
]
=
(
int8_t
)
strtol
(
strings
[
7
],
NULL
,
16
);
f
[
4
]
=
(
int8_t
)
strtol
(
strings
[
8
],
NULL
,
16
);
f
[
5
]
=
(
int8_t
)
strtol
(
strings
[
9
],
NULL
,
16
);
Serial
.
print
(
" FTW "
);
Serial
.
print
(
(
uint
)
f
[
0
]
);
Serial
.
print
(
" "
);
Serial
.
print
(
(
uint
)
f
[
1
]
);
Serial
.
print
(
" "
);
Serial
.
print
(
(
int
)
f
[
2
]
);
Serial
.
print
(
" "
);
Serial
.
print
(
(
int
)
f
[
3
]
);
Serial
.
print
(
" "
);
Serial
.
print
(
(
int
)
f
[
4
]
);
Serial
.
print
(
" "
);
Serial
.
print
(
(
int
)
f
[
5
]
);
Serial
.
print
(
"
\n
"
);
dds
->
set_frequency
(
f
);
}
}
}
}
void
print_state
(
EthernetClient
*
client
)
{
// www-browser sees this output.
client
->
print
(
"DDS:"
);
client
->
print
(
_ddsA
->
get_id
()
);
client
->
print
(
":FTW:"
);
int8_t
f
[
6
]
=
{
0
,
0
,
0
,
0
,
0
,
0
};
_ddsA
->
get_frequency
(
f
);
client
->
print
(
(
int
)
f
[
0
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
1
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
2
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
3
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
4
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
5
]
);
client
->
println
(
"<BR>"
);
serial_printf
(
"fA = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
\n
"
,
(
int8_t
)
f
[
5
],
f
[
4
],
f
[
3
],
f
[
2
],
f
[
1
],(
int8_t
)
f
[
0
]
);
client
->
print
(
"DDS:"
);
client
->
print
(
_ddsB
->
get_id
()
);
client
->
print
(
":FTW:"
);
_ddsB
->
get_frequency
(
f
);
client
->
print
(
(
int
)
f
[
0
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
1
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
2
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
3
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
4
]
);
client
->
print
(
":"
);
client
->
print
(
(
int
)
f
[
5
]
);
client
->
println
(
"<BR>"
);
serial_printf
(
"fB = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
\n
"
,
f
[
5
],
f
[
4
],
f
[
3
],
f
[
2
],
f
[
1
],
f
[
0
]
);
}
// print_state
private
:
EthernetServer
*
server
;
String
_httpRequest
;
AD9912
::
DDS
*
_ddsA
;
AD9912
::
DDS
*
_ddsB
;
};
// end class
}
// end namespace
#endif
scripts/ad9912_frequency.py
View file @
c6539738
...
...
@@ -10,6 +10,8 @@
"""
import
bigfloat
import
numpy
import
requests
import
time
def
ftw_dds
(
f_hz
):
""" return AD9912 1GHz SYSCLK FTW
...
...
@@ -21,15 +23,37 @@ def hz_dds(ftw):
"""
return
dds_clk
*
ftw
/
ftw_length
def
split_hex
(
ftw
):
out
=
[]
for
n
in
range
(
6
):
hexdigits
=
(
ftw
&
(
mask
<<
n
*
8
)
)
>>
n
*
8
print
(
"
%
x "
%
hexdigits
)
out
.
append
(
hexdigits
)
return
out
dds_clk
=
1.0e9
ftw_length
=
pow
(
2
,
48
)
# nominally we get zero output frequency with these
# tuning-wrods:
FTW1
=
0x004189374bc6
FTW1
=
0x004289374bc6
FTW1
=
0x004189374bc6
mask
=
0x0000000000ff
#FTW1 = 0x004289374bc6
f_hz_1
=
hz_dds
(
FTW1
)
print
(
"0x
%012
x
\t
%.9
f"
%
(
FTW1
,
f_hz_1
))
f1
=
hz_dds
(
FTW1
)
print
(
[
"
%02
x"
%
dig
for
dig
in
split_hex
(
FTW1
)],
" "
,
"
%.12
f"
%
f1
)
for
n
in
range
(
1
):
f
=
400e6
+
2e6
*
n
FTW1
=
int
(
ftw_dds
(
f
)
)
hexs
=
split_hex
(
FTW1
)
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://192.168.1.18/DDS:0:FTW:
%
s'
%
ftw_string
)
print
(
f
)
time
.
sleep
(
1
)
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