Skip to content

Instantly share code, notes, and snippets.

@acidobinario
Created April 23, 2024 00:25
Show Gist options
  • Save acidobinario/161d03fca9142b5bcc1e748e44f3c1c7 to your computer and use it in GitHub Desktop.
Save acidobinario/161d03fca9142b5bcc1e748e44f3c1c7 to your computer and use it in GitHub Desktop.
Geiger counter FTM wifi esp32-S2/S3
#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