Skip to content

Commit 38be00b

Browse files
authored
Merge pull request #25 from thodob/wifi_gui_draft
Utlrasonic Ranging WiFi GUI draft with functional raw data plotting
2 parents 7b9cc43 + 73adae1 commit 38be00b

6 files changed

Lines changed: 149 additions & 107 deletions

File tree

docs/Projects/UltraSound-WiFi-GUI.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,38 @@ nav_order: 2
1212
---
1313

1414
{: .WARNING}
15-
This project is currently in its initial development phase and is subject to significant changes, updates, and improvements.
15+
This project is in an early draft state. The WiFi GUI currently supports only raw data streaming with the provided Arduino WiFi example. Many UI elements are placeholders and non-functional.
16+
1617

1718
- TOC
1819
{:toc}
1920

2021

2122
## Introduction
2223

23-
For the whole ultrasonic implementation info etc, refer to main [Ultrasonic Ranging page]({% link Projects/UltraSound.md %}). This page contains only difference showcase: WiFi implementation and GUI.
24+
For the whole ultrasonic implementation info etc, refer to main [Ultrasonic Ranging page]({% link Projects/UltraSound.md %}). This page focuses on differences: WiFi implementation and GUI.
25+
26+
## Current status
27+
A draft GUI (WiFi_GUI.mlapp) is now included. In its current form, the GUI works with the **UltraSound-WiFi-GUI**, but displays only raw signals. The GUI application will need to be adapted to get the full detailed readings.
28+
29+
Functional UI elements:
30+
- IP Address text field (to target the device on the network)
31+
- Start and Stop buttons (begin/end raw data streaming)
32+
- Main Axes (live plot for incoming raw data)
33+
34+
The other UI elements are non-functional dupes and will still have to be implemented.
35+
36+
TO DO:
37+
- Filtered / XCORR / Distance buttons
38+
- CLI for outputs
39+
- simple / detailed data transmission
40+
- save plots / data
41+
- proper axis names
42+
- if the data is not received due to poor connection, don't crash the app, just skip one iteration and clean the buffers
2443

25-
## Ideas
26-
* For simplicity, use just one channel
27-
* Button to start/stop continuous measurement
28-
* Button to do x1 one shot measurement
29-
* Button to switch between detailed data transmission or only distances
30-
* Tabs to switch between views: distance only like real time running, then raw data, filtered, xcorr
31-
* If only distances selected, tabs related to raw data, filtered etc. are grayed out
44+
Current draft:
45+
![alt text]({{site.baseurl}}/assets/images/wifi_gui_draft.png)
3246

33-
Rough sketch (you can change it a lot according to needs):
47+
Full planned sketch:
3448
![alt text]({{site.baseurl}}/assets/images/gui_sketch.png)
3549

36-
Old one as a reference:
37-
![alt text]({{site.baseurl}}/assets/images/gui_old.png)
28.5 KB
Loading

projects/UltraSound-WiFi-GUI/SineLUT.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const uint16_t dac_cycle_num = 10;
66
const uint16_t sine_lut_size = 64;
77
const SENSEDU_DAC_BUFFER(sine_lut, sine_lut_size) = {
88
0x800, 0x831, 0x861, 0x890, 0x8BE, 0x8EA, 0x914, 0x93B, 0x95F, 0x980, 0x99D, 0x9B6, 0x9CB, 0x9DB, 0x9E7, 0x9EE,
9-
0x9F0, 0x9EE, 0x9E7, 0x9DB, 0x9CB, 0x9B6, 0x99D, 0x980, 0x95F, 0x93B, 0x914, 0x8EA, 0x8BE, 0x890, 0x861, 0x831,
10-
0x800, 0x7CF, 0x79F, 0x770, 0x742, 0x716, 0x6EC, 0x6C5, 0x6A1, 0x680, 0x663, 0x64A, 0x635, 0x625, 0x619, 0x612,
11-
0x610, 0x612, 0x619, 0x625, 0x635, 0x64A, 0x663, 0x680, 0x6A1, 0x6C5, 0x6EC, 0x716, 0x742, 0x770, 0x79F, 0x7CF
9+
0x9F0, 0x9EE, 0x9E7, 0x9DB, 0x9CB, 0x9B6, 0x99D, 0x980, 0x95F, 0x93B, 0x914, 0x8EA, 0x8BE, 0x890, 0x861, 0x831,
10+
0x800, 0x7CF, 0x79F, 0x770, 0x742, 0x716, 0x6EC, 0x6C5, 0x6A1, 0x680, 0x663, 0x64A, 0x635, 0x625, 0x619, 0x612,
11+
0x610, 0x612, 0x619, 0x625, 0x635, 0x64A, 0x663, 0x680, 0x6A1, 0x6C5, 0x6EC, 0x716, 0x742, 0x770, 0x79F, 0x7CF
1212
};

projects/UltraSound-WiFi-GUI/UltraSound-WiFi-GUI.ino

Lines changed: 111 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@
33
#include "SineLUT.h"
44
#include "FilterTaps.h"
55
#include "DACWave.h" // contains wave and its size
6+
#include <WiFi.h>
67

78
uint32_t lib_error = 0;
89
uint8_t error_led = D86;
910

1011
/* -------------------------------------------------------------------------- */
1112
/* Settings */
1213
/* -------------------------------------------------------------------------- */
14+
#define WIFI_SSID "Holohouse"
15+
#define WIFI_PASS "FubuKing2011"
16+
#define WIFI_PORT 80
17+
1318
#define IS_TRANSMIT_DETAILED_DATA true // activate full raw, filtered, xcorr data transmission
1419
#define BAN_DISTANCE 20 // min distance [cm] - how many self reflections cancelled
1520
#define ACTUAL_SAMPLING_RATE 250000 // You need to measure this value using a wave generator with a fixed e.g. 1kHz Sine
1621
#define STORE_BUF_SIZE 32 * 32 // 2400 for 1 measurement per second.
17-
// only multiples of 32!!!!!! (64 chunk size of bytes, so 32 for 16bit)
22+
// only multiples of 32!!!!!! (64 chunk size of bytes, so 32 for 16bit)
1823

1924
/* --------------------------------- Filter --------------------------------- */
2025
#define FILTER_BLOCK_LENGTH 32 // how many samples we want to process every time we call the fir process function AT
@@ -52,13 +57,23 @@ SensEdu_ADC_Settings adc1_settings = {
5257
};
5358

5459
/* ----------------------------------- DAC ---------------------------------- */
55-
DAC_Channel* dac_channel = DAC_CH1;
5660
// lut settings are in SineLUT.h
5761
#define DAC_SINE_FREQ 32000 // 32kHz
5862
#define DAC_SAMPLE_RATE DAC_SINE_FREQ * sine_lut_size // 64 samples per one sine cycle
5963

60-
SensEdu_DAC_Settings dac_settings = {dac_channel, DAC_SAMPLE_RATE, (uint16_t*)sine_lut, sine_lut_size,
61-
SENSEDU_DAC_MODE_BURST_WAVE, dac_cycle_num}; // specifying burst mode
64+
DAC_Channel* dac_ch = DAC_CH1;
65+
SensEdu_DAC_Settings dac_settings = {
66+
.dac_channel = dac_ch,
67+
.sampling_freq = DAC_SAMPLE_RATE,
68+
.mem_address = (uint16_t*)sine_lut,
69+
.mem_size = sine_lut_size,
70+
.wave_mode = SENSEDU_DAC_MODE_BURST_WAVE,
71+
.burst_num = dac_cycle_num
72+
};
73+
74+
/* ---------------------------------- WiFi ---------------------------------- */
75+
int status = WL_IDLE_STATUS;
76+
WiFiServer server(WIFI_PORT);
6277

6378
/* -------------------------------------------------------------------------- */
6479
/* Constants */
@@ -101,66 +116,84 @@ void setup() {
101116
SensEdu_ADC_Init(&adc1_settings);
102117
SensEdu_ADC_Enable(adc1);
103118

104-
lib_error = SensEdu_GetError();
105-
while (lib_error != 0) {
106-
handle_error();
119+
check_lib_errors();
120+
121+
// attempt connection to WiFi network
122+
while (status != WL_CONNECTED) {
123+
Serial.print("Attempting to connect to SSID: ");
124+
Serial.println(WIFI_SSID);
125+
// connect to WPA/WPA2 network (change this if youre using open / WEP network)
126+
status = WiFi.begin(WIFI_SSID, WIFI_PASS);
127+
128+
// wait 10 seconds for connection:
129+
delay(10000);
107130
}
131+
server.begin();
132+
// connection established; print out the status:
133+
print_wifi_status();
108134
}
109135

110136
/* -------------------------------------------------------------------------- */
111137
/* Loop */
112138
/* -------------------------------------------------------------------------- */
113139

114140
void loop() {
141+
check_lib_errors();
142+
115143
SenseduBoard* main_obj_ptr = &SenseduBoardObj;
144+
145+
WiFiClient client = server.available();
146+
if (!client) {
147+
return;
148+
}
149+
Serial.println("Client connected!");
150+
116151
// Measurement is initiated by the signal from computing device (matlab script)
117-
static char serial_buf = 0;
118-
119-
// Measurement is initiated by signal from computing device
120-
while (1) {
121-
while (Serial.available() == 0); // Wait for a signal
122-
serial_buf = Serial.read();
123-
if (serial_buf == 't') {
124-
break;
152+
static char buf = 0;
153+
154+
while(client.connected()) {
155+
if (!client.available()) {
156+
continue;
125157
}
126-
}
127-
128-
// Start dac->adc sequence
129-
SensEdu_DAC_Enable(dac_channel);
130-
while(!SensEdu_DAC_GetBurstCompleteFlag(dac_channel)); // wait for dac to finish sending the burst
131-
SensEdu_DAC_ClearBurstCompleteFlag(dac_channel);
132-
133-
// Start ADCs
134-
SensEdu_ADC_Start(adc1);
135-
136-
// Wait for the data from ADC1
137-
while(!SensEdu_ADC_GetTransferStatus(adc1));
138-
SensEdu_ADC_ClearTransferStatus(adc1);
139-
140-
// Calculating distance for each microphone
141-
static uint32_t distance[adc1_mic_num];
142-
for(uint8_t i = 0; i < adc1_mic_num; i++) {
143-
process_and_transmit_data(main_obj_ptr->processing_buffer, STORE_BUF_SIZE, adc1_data, STORE_BUF_SIZE, main_obj_ptr->ban_flag, IS_TRANSMIT_DETAILED_DATA);
144-
distance[i] = calculate_distance(main_obj_ptr->processing_buffer);
145-
}
146158

147-
// Sending the distance measurements
148-
for (uint8_t i = 0; i < (adc1_mic_num); i++) {
149-
Serial.write((const uint8_t *) &distance[i], 4);
150-
}
159+
buf = client.read();
160+
if (buf != 't') { // trigger not detected
161+
continue;
162+
}
151163

152-
// check errors
153-
lib_error = SensEdu_GetError();
154-
while (lib_error != 0) {
155-
handle_error();
164+
// Start dac->adc sequence
165+
SensEdu_DAC_Enable(dac_ch);
166+
while(!SensEdu_DAC_GetBurstCompleteFlag(dac_ch)); // wait for dac to finish sending the burst
167+
SensEdu_DAC_ClearBurstCompleteFlag(dac_ch);
168+
169+
// Start ADC
170+
SensEdu_ADC_Start(adc1);
171+
172+
// Wait for the data from ADC1
173+
while(!SensEdu_ADC_GetTransferStatus(adc1));
174+
SensEdu_ADC_ClearTransferStatus(adc1);
175+
176+
// Calculating distance for each microphone
177+
static uint32_t distance[adc1_mic_num];
178+
for(uint8_t i = 0; i < adc1_mic_num; i++) {
179+
process_and_transmit_data(client, main_obj_ptr->processing_buffer, STORE_BUF_SIZE, adc1_data, STORE_BUF_SIZE, main_obj_ptr->ban_flag, IS_TRANSMIT_DETAILED_DATA);
180+
distance[i] = calculate_distance(main_obj_ptr->processing_buffer);
181+
}
182+
183+
// Sending the distance measurements
184+
for (uint8_t i = 0; i < (adc1_mic_num); i++) {
185+
client.write((const uint8_t *) &distance[i], 4);
186+
}
187+
188+
check_lib_errors();
156189
}
157190
}
158191

159-
void process_and_transmit_data(float* buf, const uint16_t buf_size, uint16_t* ch_array, const uint16_t ch_array_size, uint8_t ban_flag, uint8_t is_detailed_transmission) {
192+
void process_and_transmit_data(WiFiClient& client, float* buf, const uint16_t buf_size, uint16_t* ch_array, const uint16_t ch_array_size, uint8_t ban_flag, uint8_t is_detailed_transmission) {
160193

161194
/* -------------------------------- RAW DATA -------------------------------- */
162195
if (is_detailed_transmission)
163-
transfer_serial_data(ch_array, ch_array_size, 32);
196+
transfer_wifi_data(client, ch_array, ch_array_size);
164197

165198
/* --------------------- RESCALED, FILTERED, NO COUPLED --------------------- */
166199
// Rescale from [0, (2^16-1)] to [-1, 1] and filter around 32 kHz
@@ -171,30 +204,50 @@ void process_and_transmit_data(float* buf, const uint16_t buf_size, uint16_t* ch
171204
remove_coupling(buf, c_banned_sample_num);
172205
}
173206
if (is_detailed_transmission)
174-
transfer_serial_data_float(buf, buf_size, 32);
207+
transfer_wifi_data_float(client, buf, buf_size);
175208

176209
/* ---------------------------------- XCORR --------------------------------- */
177210
custom_xcorr(buf, dac_wave, buf_size);
178211
if (is_detailed_transmission)
179-
transfer_serial_data_float(buf, buf_size, 32);
212+
transfer_wifi_data_float(client, buf, buf_size);
180213

181214
}
182215

183-
void transfer_serial_data(uint16_t* data, const uint16_t data_length, const uint16_t chunk_size_byte) {
184-
for (uint16_t i = 0; i < (data_length*2); i += chunk_size_byte) {
185-
uint16_t transfer_size = ((data_length*2) - i < chunk_size_byte) ? (data_length*2 - i) : chunk_size_byte;
186-
Serial.write((const uint8_t *) data + i, transfer_size);
187-
}
216+
void transfer_wifi_data(WiFiClient& client, uint16_t* data, const uint16_t data_length) {
217+
client.write((const uint8_t*)data, data_length * sizeof(uint16_t));
188218
}
189219

190-
void transfer_serial_data_float(float* data, const uint16_t data_length, const uint16_t chunk_size_byte) {
191-
for (uint16_t i = 0; i < (data_length*4); i += chunk_size_byte) {
192-
uint16_t transfer_size = ((data_length*4) - i < chunk_size_byte) ? (data_length*4 - i) : chunk_size_byte;
193-
Serial.write((const uint8_t *) data + i, transfer_size);
220+
void transfer_wifi_data_float(WiFiClient& client, float* data, const uint16_t data_length) {
221+
client.write((const uint8_t*)data, data_length * sizeof(float));
222+
}
223+
224+
void check_lib_errors(void) {
225+
lib_error = SensEdu_GetError();
226+
while (lib_error != 0) {
227+
handle_error();
194228
}
195229
}
196230

197-
void handle_error() {
198-
// serial is taken by matlab, use LED as indication
231+
void handle_error(void) {
199232
digitalWrite(error_led, LOW);
233+
Serial.print("Error: 0x");
234+
Serial.println(lib_error, HEX);
235+
delay(1000);
236+
}
237+
238+
void print_wifi_status(void) {
239+
// print the SSID of the network youre connected to
240+
Serial.print("SSID: ");
241+
Serial.println(WiFi.SSID());
242+
243+
// print your boards local IP address
244+
IPAddress ip = WiFi.localIP();
245+
Serial.print("IP Address: ");
246+
Serial.println(ip);
247+
248+
// print the received WiFi signal strength
249+
long rssi = WiFi.RSSI();
250+
Serial.print("signal strength (RSSI):");
251+
Serial.print(rssi);
252+
Serial.println(" dBm");
200253
}
47.2 KB
Binary file not shown.

projects/UltraSound-WiFi-GUI/matlab/detailed_data_acquisition.m renamed to projects/UltraSound-WiFi-GUI/matlab/app_functionality_template.m

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
%% detailed_data_acquisition.m
2-
% triggers ultrasonic recording
3-
% receives the data
4-
% plots distances along with processing steps
1+
%% demo file to see what needs to be implemented via interface
2+
%% see actual code at matlab -> apps -> design app -> open -> WiFi_GUI.mlapp
53
clear;
64
close all;
75
addpath("plot scripts\");
@@ -16,9 +14,10 @@
1614

1715
%% Arduino Setup + Config
1816
% Serial port configuration
19-
ARDUINO_PORT = 'COM18';
20-
ARDUINO_BAUDRATE = 115200;
21-
arduino = serialport(ARDUINO_PORT, ARDUINO_BAUDRATE); % select port and baudrate
17+
ARDUINO_IP = "192.168.56.128"; % match to Arduino IP
18+
ARDUINO_PORT = 80; % match to port of Arduino server
19+
20+
arduino = tcpclient(ARDUINO_IP, ARDUINO_PORT, "Timeout",30, "ConnectTimeout",30); % connect to Arduino
2221

2322
%% Arrays
2423
dist_matrix = zeros(MIC_NUM, ITERATIONS); % distance matrix
@@ -63,7 +62,7 @@
6362
fprintf("Data acquisition completed in: %fsec\n", acquisition_time);
6463

6564
% close serial connection
66-
arduino = [];
65+
%arduino = [];
6766

6867
%% Plotting 1
6968
figure
@@ -156,35 +155,13 @@ function plot_detailed_data(mic, step, data)
156155
end
157156

158157
function data = read_16bit_data(arduino, data_length)
159-
chunk_size = 32; % in bytes
160-
data_length_byte = data_length*2; % multiplied by sizeof(type)
161-
162-
raw_data_8bit = zeros(data_length_byte/chunk_size, chunk_size);
163-
raw_data_16bit = zeros(data_length_byte/chunk_size, chunk_size/2);
164-
165-
for i = 1:(data_length_byte/chunk_size)
166-
raw_data_8bit(i, :) = read(arduino, chunk_size, 'uint8');
167-
raw_data_16bit(i, :) = typecast_uint8_uint16(raw_data_8bit(i, :));
168-
end
169-
170-
% rearrange by mic
171-
data = reshape(raw_data_16bit', 1, []);
158+
raw_data = read(arduino, data_length * 2, 'uint8');
159+
data = typecast_uint8_uint16(raw_data);
172160
end
173161

174162
function data = read_float_data(arduino, data_length)
175-
chunk_size = 32; % in bytes
176-
data_length_byte = data_length*4; % multiplied by sizeof(type)
177-
178-
raw_data_8bit = zeros(data_length_byte/chunk_size, chunk_size);
179-
raw_data_float = zeros(data_length_byte/chunk_size, chunk_size/4);
180-
181-
for i = 1:(data_length_byte/chunk_size)
182-
raw_data_8bit(i, :) = read(arduino, chunk_size, 'uint8');
183-
raw_data_float(i, :) = typecast_uint8_float(raw_data_8bit(i, :));
184-
end
185-
186-
% rearrange by mic
187-
data = reshape(raw_data_float', 1, []);
163+
raw_data = read(arduino, data_length * 4, 'uint8');
164+
data = typecast_uint8_float(raw_data);
188165
end
189166

190167
function casted_data = typecast_uint8_uint16(data)

0 commit comments

Comments
 (0)