Created
April 23, 2024 00:25
-
-
Save acidobinario/161d03fca9142b5bcc1e748e44f3c1c7 to your computer and use it in GitHub Desktop.
Geiger counter FTM wifi esp32-S2/S3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "WiFi.h" | |
#include <Arduino.h> | |
#include <freertos/FreeRTOS.h> | |
#include <freertos/task.h> | |
/* | |
THIS FEATURE IS SUPPORTED ONLY BY ESP32-S2 AND ESP32-C3 | |
*/ | |
// Change the SSID and PASSWORD here if needed | |
const char *WIFI_FTM_SSID = "WiFi_FTM_Responder"; // SSID of AP that has FTM Enabled | |
const char *WIFI_FTM_PASS = "ftm_responder"; // STA Password | |
// FTM settings | |
// Number of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0 (No pref), 16, 24, 32, 64) | |
const uint8_t FTM_FRAME_COUNT = 64; | |
// Requested time period between consecutive FTM bursts in 100’s of milliseconds (allowed values - 0 (No pref) or 2-255) | |
const uint16_t FTM_BURST_PERIOD = 2; | |
// Semaphore to signal when FTM Report has been received | |
SemaphoreHandle_t ftmSemaphore; | |
// Status of the received FTM Report | |
bool ftmSuccess = true; | |
volatile float latestDistance; // Shared variable (requires synchronization) | |
const int buzzerPin = 11; //buzzer to arduino pin 11 | |
unsigned long lastMillis = 0; | |
int buzzerState = LOW; | |
// FTM report handler with the calculated data from the round trip | |
// WARNING: This function is called from a separate FreeRTOS task (thread)! | |
void onFtmReport(arduino_event_t *event) { | |
const char *status_str[5] = { "SUCCESS", "UNSUPPORTED", "CONF_REJECTED", "NO_RESPONSE", "FAIL" }; | |
wifi_event_ftm_report_t *report = &event->event_info.wifi_ftm_report; | |
// Set the global report status | |
ftmSuccess = report->status == FTM_STATUS_SUCCESS; | |
if (ftmSuccess) { | |
// The estimated distance in meters may vary depending on some factors (see README file) | |
latestDistance = (float)report->dist_est / 100.0 ; | |
Serial.printf("FTM Estimate: Distance: %.2f m, Return Time: %lu ns\n", (float)report->dist_est / 100.0, report->rtt_est); | |
// Pointer to FTM Report with multiple entries, should be freed after use | |
free(report->ftm_report_data); | |
} else { | |
Serial.print("FTM Error: "); | |
Serial.println(status_str[report->status]); | |
free(report->ftm_report_data); | |
} | |
// Signal that report is received | |
xSemaphoreGive(ftmSemaphore); | |
} | |
// Initiate FTM Session and wait for FTM Report | |
bool getFtmReport() { | |
if (!WiFi.initiateFTM(FTM_FRAME_COUNT, FTM_BURST_PERIOD)) { | |
Serial.println("FTM Error: Initiate Session Failed"); | |
delay(100); | |
} | |
// Wait for signal that report is received and return true if status was success | |
return xSemaphoreTake(ftmSemaphore, portMAX_DELAY) == pdPASS && ftmSuccess; | |
} | |
void getFtmReportTask(void * parameter) { | |
for(;;) { // infinite loop | |
getFtmReport(); | |
vTaskDelay(1000 / portTICK_PERIOD_MS); // delay for 2 seconds | |
} | |
} | |
void buzzerTask(void * parameter) { | |
for(;;) { | |
// calculate the base delay between each click based on the distance | |
// if the distance is 10 meters or more, the base delay will be 3000 ms (1 click every 3 seconds) | |
// if the distance is 1 meter or less, the base delay will be 30 ms (about 33 clicks per second) | |
// for distances between 1 and 10 meters, the base delay will be between 30 and 3000 ms | |
int baseDelayMs = map(latestDistance, 0, 15, 10, 600); | |
// add a random variation of up to 150 ms to the base delay | |
int delayMs = baseDelayMs - 75 + random(150); | |
// ensure that delayMs is not less than 0 | |
if (delayMs < 0) { | |
delayMs = 0; | |
} | |
// there is a 20% chance that there is no delay at all | |
if (random(100) < 20) { | |
delayMs = 0; | |
} | |
// the frequency of the buzzing is random between 350 and 550 kHz | |
int frequency = random(350, 551); | |
// make the buzzer click | |
tone(buzzerPin, frequency); | |
delay(10); // short delay to make the click | |
noTone(buzzerPin); | |
// delay for the calculated time | |
vTaskDelay(delayMs / portTICK_PERIOD_MS); | |
} | |
}; | |
void setup() { | |
Serial.begin(9600); | |
// Create binary semaphore (initialized taken and can be taken/given from any thread/ISR) | |
ftmSemaphore = xSemaphoreCreateBinary(); | |
pinMode(buzzerPin, OUTPUT); // Set buzzer | |
// Will call onFtmReport() from another thread with FTM Report events. | |
WiFi.onEvent(onFtmReport, ARDUINO_EVENT_WIFI_FTM_REPORT); | |
// Connect to AP that has FTM Enabled | |
Serial.println("Connecting to FTM Responder"); | |
WiFi.begin(WIFI_FTM_SSID, WIFI_FTM_PASS); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi Connected"); | |
Serial.print("Initiating FTM session with Frame Count "); | |
Serial.print(FTM_FRAME_COUNT); | |
Serial.print(" and Burst Period "); | |
Serial.print(FTM_BURST_PERIOD * 100); | |
Serial.println(" ms"); | |
// create the tasks | |
xTaskCreate(getFtmReportTask, "Get FTM Report Task", 10000, NULL, 1, NULL); | |
xTaskCreate(buzzerTask, "Buzzer Task", 10000, NULL, 1, NULL); | |
} | |
void loop() { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment