diff --git a/README.md b/README.md index be722ee..302420f 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,23 @@ # waterfall -A waterfall spectrum analyzer for the ADALM-PLUTO, written in Odin, using fenster and libiio. Only on X11 (for now?). +A waterfall spectrum analyzer for the ADALM-PLUTO SDR, written in Odin, using fenster and libiio. Only on X11 (for now?). This is a project that was made for the University of Twente First year's Electrical Engineering Wireless transmission project of 2023. ## Dependencies -X11 (so basically, Linux), [Odin](https://github.com/odin-lang/Odin), [libiio](https://github.com/analogdevicesinc/libiio), bash +Linux, X11, [Odin](https://github.com/odin-lang/Odin), [libiio](https://github.com/analogdevicesinc/libiio), bash, gcc ## Building and running First you build it:\ `$ ./make.sh`\ -Then you can run it:\ +Then, connect the ADALM-PLUTO to your pc.\ +Now you can run it:\ `$ ./waterfall`\ -It should bring up the window. Running it in the terminal is highly recommended. +It should bring up the window. ## Usage -The middle of the screen is the '0-frequency' of the complex fourier transform. Pressing the up-and-down arrow keys changes the frequency that the ADALM 'focuses' on. -How to actually interpret that is unclear, but I suspect it changes the center frequency as well. +Pressing the up-and-down arrow keys changes the frequency that the ADALM-PLUTO 'focuses' on, and with it, the center frequency.\ +The center frequency is at the middle of the screen. ## Details -It starts at 100MHz, a sampling rate of 60MHz (whatever that entails exactly), and an FFT bin size of 1024.\ +It starts at 100MHz, a sampling rate of 60MHz (whatever that entails exactly), and an FFT bin size of 1024. Every frame is normalized, so if there's no one loud signal, you will see a lot of noise.\ In this repo, there are functions for reading and writing .WAV files, which can be implemented quite easily.\ There is currently a memory leak and more wierdness going on with closing the device and destroying the buffer. I am not sure why it won't destroy the buffer properly. diff --git a/main.odin b/main.odin index f03993e..d619955 100644 --- a/main.odin +++ b/main.odin @@ -9,13 +9,13 @@ import "wav" import "iio" main :: proc() { - level :: uint(10) - bin_size :: 1 << level + level := uint(10) + bin_size := uint(1 << level) sample_rate :: 60_000_000 focus_freq := 100_000_000 history_size :: 800 - info := iio.prep_and_get_device(iio.STANDARD_IP, focus_freq, sample_rate, bin_size) + info := iio.prep_and_get_device(iio.STANDARD_IP, focus_freq, sample_rate, int(bin_size)) if !info.success do return // defer iio.undo_device(&info) @@ -43,9 +43,11 @@ main :: proc() { delete(freqs_buffer) } - was_pressed := false + arrow_was_pressed := false + space_was_pressed := false + paused := false for !fenster.loop(fen) { - for y := fen.height - 1; y > 0 ; y -= 1 { + if !paused do for y := fen.height - 1; y > 0 ; y -= 1 { this_line := scr_buf[fen.width*y : fen.width*(y+1)] next_line := scr_buf[fen.width*(y-1) : fen.width*y] copy(this_line, next_line) @@ -61,22 +63,51 @@ main :: proc() { } } - pressed := false + /* coloured subdivisions */ + { + for k: uint = bin_size >> 2; k < bin_size; k += (bin_size >> 2){ + x := int(k) + y := history_size - 20 + fen.buf[x + int(fen.width)*y] = fenster.RED + } + for k: uint = bin_size >> 3; k < bin_size; k += (bin_size >> 2){ + x := int(k) + y := history_size - 10 + fen.buf[x + int(fen.width)*y] = fenster.RED + } + for k: uint = bin_size >> 4; k < bin_size; k += (bin_size >> 3){ + x := int(k) + y := history_size - 5 + fen.buf[x + int(fen.width)*y] = fenster.BLUE + } + for k: uint = bin_size >> 5; k < bin_size; k += (bin_size >> 4){ + x := int(k) + y := history_size - 5 + fen.buf[x + int(fen.width)*y] = fenster.GREEN + } + } + + arrow_pressed := false + space_pressed := false freq_jump := 0 if fen.keys[ARROW_KEY.UP] { - pressed = true + arrow_pressed = true freq_jump = 10_000_000 } if fen.keys[ARROW_KEY.DOWN] { - pressed = true + arrow_pressed = true freq_jump = -10_000_000 } + if fen.keys[SPACE_KEY] { + space_pressed = true + } + if space_pressed && !space_was_pressed do paused = !paused - if pressed && !was_pressed { + if arrow_pressed && !arrow_was_pressed { focus_freq += freq_jump fmt.printf("new center frequency: %d MHz...", focus_freq/1_000_000) // iio.undo_device(&info) /* this crashes, so it's commented out for now, even though it leaks memory */ - info := iio.prep_and_get_device(iio.STANDARD_IP, focus_freq, sample_rate, bin_size) + info := iio.prep_and_get_device(iio.STANDARD_IP, focus_freq, sample_rate, int(bin_size)) if !info.success { fmt.printf(" failed :(\n") return @@ -84,7 +115,8 @@ main :: proc() { fmt.printf(" success!\n") } - was_pressed = pressed + arrow_was_pressed = arrow_pressed + space_was_pressed = space_pressed if fen.keys[ESC_KEY] || fen.keys['Q'] do break } diff --git a/make.sh b/make.sh index 817f923..d8367d2 100755 --- a/make.sh +++ b/make.sh @@ -1,3 +1,5 @@ +set -e + (cd iio; bash make_lib.sh) (cd fenster; bash make_lib.sh)