Initial Commit.

This commit is contained in:
Afonso Clerigo Mendes de Sousa 2026-03-31 19:42:54 +01:00
commit 4a081c8058
16 changed files with 7558 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build/*
build
.cache
.cache/*

3
CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(smart_adress)

10
Makefile Normal file
View File

@ -0,0 +1,10 @@
flash:
idf.py -p /dev/cu.usbserial-0001 flash
run:
idf.py -p /dev/cu.usbserial-0001 flash monitor
build:
idf.py set-target esp32
idf.py build
run

188
local/CMakeLists.txt Normal file
View File

@ -0,0 +1,188 @@
cmake_minimum_required(VERSION 3.20)
project(CPP_TEMPLATE VERSION 0.1.0 LANGUAGES C CXX)
# Set C++ standard
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Set C standard
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
# Export compile commands for IDE support (clangd, etc.)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Create symlink to compile_commands.json in project root for LSP
if(CMAKE_EXPORT_COMPILE_COMMANDS)
add_custom_target(symlink_compile_commands ALL
COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_SOURCE_DIR}/compile_commands.json
COMMENT "Creating symlink to compile_commands.json in project root"
)
endif()
# Set output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Build type defaults
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type" FORCE)
endif()
# Options
option(ENABLE_SANITIZERS "Enable address and undefined behavior sanitizers" ON)
option(ENABLE_STATIC_ANALYSIS "Enable static analysis warnings" ON)
set(OUTPUT_NAME "" CACHE STRING "Name of the output executable (defaults to project name)")
# Gather source files (avoid GLOB_RECURSE - explicitly list files is better practice)
# But keeping it for template flexibility
file(GLOB_RECURSE PROJECT_SOURCES
${CMAKE_SOURCE_DIR}/source/*.cpp
${CMAKE_SOURCE_DIR}/source/*.c
)
file(GLOB_RECURSE LIBRARY_SOURCES
${CMAKE_SOURCE_DIR}/libraries/*.cpp
${CMAKE_SOURCE_DIR}/libraries/*.c
)
# Don't glob headers from include/ as sources (they should only be included)
file(GLOB_RECURSE PROJECT_HEADERS
${CMAKE_SOURCE_DIR}/include/*.hpp
${CMAKE_SOURCE_DIR}/include/*.h
${CMAKE_SOURCE_DIR}/libraries/*.hpp
${CMAKE_SOURCE_DIR}/libraries/*.h
${CMAKE_SOURCE_DIR}/source/*.hpp
${CMAKE_SOURCE_DIR}/source/*.h
)
# Combine all sources
set(ALL_SOURCES ${PROJECT_SOURCES} ${LIBRARY_SOURCES})
# Determine executable name
if(OUTPUT_NAME)
set(EXECUTABLE_NAME ${OUTPUT_NAME})
else()
set(EXECUTABLE_NAME ${PROJECT_NAME})
endif()
# Create executable
add_executable(${EXECUTABLE_NAME} ${ALL_SOURCES})
# Set target properties
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
OUTPUT_NAME ${EXECUTABLE_NAME}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
# Include directories - use target-specific commands
target_include_directories(${EXECUTABLE_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libraries
)
# Compiler-specific flags
if(MSVC)
target_compile_options(${EXECUTABLE_NAME} PRIVATE
/W4 # Warning level 4
/permissive- # Standards conformance
/Zc:__cplusplus # Correct __cplusplus macro
/Zc:inline # Remove unreferenced COMDAT
/WX- # Don't treat warnings as errors by default
)
if(ENABLE_STATIC_ANALYSIS)
target_compile_options(${EXECUTABLE_NAME} PRIVATE /analyze)
endif()
# MSVC debug flags
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(${EXECUTABLE_NAME} PRIVATE /Zi /Od)
endif()
else() # GCC/Clang
target_compile_options(${EXECUTABLE_NAME} PRIVATE
-Wall
-Wextra
-Wpedantic
-Wshadow
-Wconversion
-Wsign-conversion
-Wuninitialized
-Wunused
-Werror=return-type
-Wcast-align
-Wformat=2
-Wnull-dereference
)
# Additional warnings for static analysis
if(ENABLE_STATIC_ANALYSIS)
target_compile_options(${EXECUTABLE_NAME} PRIVATE
-Wcast-qual
-Wdouble-promotion
-Wold-style-cast
)
endif()
# Sanitizers (Debug builds)
if(ENABLE_SANITIZERS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
# Check if sanitizers are available
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-fsanitize=address" HAS_ASAN)
check_cxx_compiler_flag("-fsanitize=undefined" HAS_UBSAN)
if(HAS_ASAN AND HAS_UBSAN)
target_compile_options(${EXECUTABLE_NAME} PRIVATE
-fsanitize=address,undefined,leak
-fno-omit-frame-pointer
-g
)
target_link_options(${EXECUTABLE_NAME} PRIVATE
-fsanitize=address,undefined,leak
)
message(STATUS "Sanitizers enabled: address, undefined, leak")
else()
message(WARNING "Sanitizers requested but not available - skipping")
endif()
endif()
# Optimization flags for Release
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_options(${EXECUTABLE_NAME} PRIVATE
-O3
-march=native
-DNDEBUG
)
endif()
# Debug flags
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(${EXECUTABLE_NAME} PRIVATE
-O0
-g3
-ggdb
)
endif()
endif()
# Print configuration summary
message(STATUS "=== Configuration Summary ===")
message(STATUS "Project: ${PROJECT_NAME} v${PROJECT_VERSION}")
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "C Standard: ${CMAKE_C_STANDARD}")
message(STATUS "Executable Name: ${EXECUTABLE_NAME}")
message(STATUS "Sanitizers: ${ENABLE_SANITIZERS}")
message(STATUS "Static Analysis: ${ENABLE_STATIC_ANALYSIS}")
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "============================")
# Optionally, enable testing
# enable_testing()
# add_subdirectory(tests)

256
local/build.sh Executable file
View File

@ -0,0 +1,256 @@
#!/bin/bash
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Unicode symbols
CHECK="✓"
CROSS="✗"
ARROW="➜"
GEAR="⚙"
HAMMER="🔨"
ROCKET="🚀"
# Default values
BUILD_TYPE="Debug"
CLEAN_BUILD=false
VERBOSE=false
JOBS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
# Print functions
print_header() {
echo -e "${BOLD}${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${BLUE}${NC} ${HAMMER} ${BOLD}${CYAN} C/C++ Project Builder${NC} ${BOLD}${BLUE}${NC}"
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
echo ""
}
print_separator() {
echo -e "${BLUE}────────────────────────────────────────────────────────${NC}"
}
print_success() {
echo -e "${GREEN}${CHECK}${NC} $1"
}
print_error() {
echo -e "${RED}${CROSS}${NC} $1"
}
print_info() {
echo -e "${CYAN}${ARROW}${NC} $1"
}
print_step() {
echo -e "${YELLOW}${GEAR}${NC} ${BOLD}$1${NC}"
}
show_progress() {
local duration=$1
local prefix=$2
local size=40
already_done() { for ((done=0; done<$elapsed; done++)); do printf "▓"; done }
remaining() { for ((remain=$elapsed; remain<$size; remain++)); do printf " "; done }
percentage() { printf "| %s%%" $(( (($elapsed)*100)/($size)*100/100 )); }
for (( elapsed=1; elapsed<=$size; elapsed++ )); do
printf "\r${CYAN}${prefix}${NC} [$(already_done)$(remaining)] $(percentage)"
sleep $(echo "scale=3; $duration/$size" | bc)
done
printf "\n"
}
usage() {
echo -e "${BOLD}Usage:${NC} $0 [OPTIONS] <executable_name>"
echo ""
echo -e "${BOLD}Options:${NC}"
echo -e " -r, --release Build in Release mode (default: Debug)"
echo -e " -c, --clean Clean build directory before building"
echo -e " -v, --verbose Verbose make output"
echo -e " -j, --jobs <N> Number of parallel jobs (default: $JOBS)"
echo -e " -h, --help Show this help message"
echo ""
echo -e "${BOLD}Examples:${NC}"
echo -e " $0 myprogram"
echo -e " $0 -r -j8 myprogram"
echo -e " $0 --clean --release myprogram"
exit 1
}
# Parse arguments
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-r|--release)
BUILD_TYPE="Release"
shift
;;
-c|--clean)
CLEAN_BUILD=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-j|--jobs)
JOBS="$2"
shift 2
;;
-h|--help)
usage
;;
*)
POSITIONAL_ARGS+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}"
# Check if executable name is provided
if [ -z "$1" ]; then
print_header
print_error "No executable name provided"
echo ""
usage
fi
EXECUTABLE_NAME=$1
# Start build process
print_header
# Build configuration info
print_info "Build Configuration:"
echo -e " ${BOLD}Executable:${NC} $EXECUTABLE_NAME"
echo -e " ${BOLD}Build Type:${NC} $BUILD_TYPE"
echo -e " ${BOLD}Jobs:${NC} $JOBS"
echo -e " ${BOLD}Clean Build:${NC} $CLEAN_BUILD"
echo ""
print_separator
echo ""
# Clean build directory if requested
if [ "$CLEAN_BUILD" = true ] && [ -d "./build" ]; then
print_step "Cleaning build directory..."
rm -rf ./build
print_success "Build directory cleaned"
echo ""
fi
# Create build directory
if [ ! -d "./build" ]; then
print_step "Creating build directory..."
mkdir -p build
print_success "Build directory created"
else
print_info "Using existing build directory"
fi
echo ""
# CMake configuration
print_step "Configuring CMake..."
print_separator
echo ""
cd ./build
CMAKE_CMD="cmake -DOUTPUT_NAME=$EXECUTABLE_NAME -DCMAKE_BUILD_TYPE=$BUILD_TYPE .."
if [ "$VERBOSE" = true ]; then
eval $CMAKE_CMD
else
eval $CMAKE_CMD > /dev/null 2>&1
fi
if [ $? -ne 0 ]; then
print_error "CMake configuration failed"
exit 1
fi
print_success "CMake configuration complete"
echo ""
# Compilation
print_step "Compiling project..."
print_separator
echo ""
MAKE_CMD="make -j$JOBS"
if [ "$VERBOSE" = true ]; then
MAKE_CMD="$MAKE_CMD VERBOSE=1"
fi
START_TIME=$(date +%s)
if [ "$VERBOSE" = true ]; then
eval $MAKE_CMD
BUILD_RESULT=$?
else
eval $MAKE_CMD 2>&1 | tee build.log | while IFS= read -r line; do
if echo "$line" | grep -q "\[.*%\]"; then
printf "\r${CYAN}${ARROW}${NC} Compiling: %s" "$line"
elif echo "$line" | grep -qE "error:|Error|ERROR"; then
echo ""
print_error "$line"
fi
done
BUILD_RESULT=${PIPESTATUS[0]}
fi
END_TIME=$(date +%s)
BUILD_TIME=$((END_TIME - START_TIME))
echo ""
if [ $BUILD_RESULT -ne 0 ]; then
print_error "Build failed!"
echo ""
print_info "Check build/build.log for details"
exit 1
fi
print_success "Compilation complete (${BUILD_TIME}s)"
echo ""
# Copy executable
print_step "Copying executable to project root..."
if [ ! -f "./bin/$EXECUTABLE_NAME" ]; then
print_error "Executable not found: ./bin/$EXECUTABLE_NAME"
exit 1
fi
cp ./bin/$EXECUTABLE_NAME ../
print_success "Executable copied"
echo ""
# Build summary
print_separator
echo -e "${BOLD}${GREEN}${ROCKET} Build Complete!${NC}"
print_separator
echo ""
echo -e "${BOLD}Summary:${NC}"
echo -e " ${BOLD}Executable:${NC} ./$EXECUTABLE_NAME"
echo -e " ${BOLD}Build Type:${NC} $BUILD_TYPE"
echo -e " ${BOLD}Build Time:${NC} ${BUILD_TIME}s"
echo -e " ${BOLD}Binary Location:${NC} ./build/bin/$EXECUTABLE_NAME"
# File size info
if command -v du &> /dev/null; then
SIZE=$(du -h "./$EXECUTABLE_NAME" | cut -f1)
echo -e " ${BOLD}Binary Size:${NC} $SIZE"
fi
echo ""
print_info "Run with: ${BOLD}./$EXECUTABLE_NAME${NC}"
echo ""

1
local/compile_commands.json Symbolic link
View File

@ -0,0 +1 @@
/Users/AfonsoCMSosua/Developer/prod_final/ESP32/local/build/compile_commands.json

0
local/include/.gitkeep Normal file
View File

0
local/libraries/.gitkeep Normal file
View File

BIN
local/listener Executable file

Binary file not shown.

72
local/source/main.cpp Normal file
View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 5005
#define BUF_SIZE 512
double nmea_to_decimal(const char *nmea, char direction) {
double val = atof(nmea);
int deg = (int)(val / 100);
double min = val - deg * 100;
double dec = deg + min / 60.0;
if (direction == 'S' || direction == 'W') dec = -dec;
return dec;
}
int main() {
int sockfd;
struct sockaddr_in server_addr, client_addr;
char buffer[BUF_SIZE];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) { perror("socket failed"); return 1; }
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed"); return 1;
}
printf("Listening on UDP port %d...\n", PORT);
while (1) {
socklen_t addr_len = sizeof(client_addr);
int n = recvfrom(sockfd, buffer, BUF_SIZE - 1, 0, (struct sockaddr *)&client_addr, &addr_len);
if (n < 0) { perror("recvfrom failed"); break; }
buffer[n] = '\0';
char *line = strtok(buffer, "\n");
while (line != NULL) {
if (strncmp(line, "$GPGGA", 6) == 0) {
char *tokens[15];
char *ptr = strtok(line, ",");
int i = 0;
while (ptr != NULL && i < 15) {
tokens[i++] = ptr;
ptr = strtok(NULL, ",");
}
if (i >= 7 && atoi(tokens[6]) > 0) { // fix quality > 0
double lat = nmea_to_decimal(tokens[2], tokens[3][0]);
double lon = nmea_to_decimal(tokens[4], tokens[5][0]);
double alt = atof(tokens[9]);
printf("Latitude: %.6f | Longitude: %.6f | Altitude: %.2f m | Fix: %s\n",
lat, lon, alt, tokens[6]);
} else {
printf("No valid fix yet.\n");
}
}
line = strtok(NULL, "\n");
}
}
close(sockfd);
return 0;
}

5
main/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
idf_component_register(
SRCS "main.c" "log.c"
INCLUDE_DIRS "."
REQUIRES driver freertos esp_rom esp_event esp_wifi nvs_flash esp_driver_gpio esp_driver_uart
)

102
main/log.c Normal file
View File

@ -0,0 +1,102 @@
#include "log.h"
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
unsigned int flogf(unsigned short flags, const char *Format, ...) {
va_list args;
va_start(args, Format);
unsigned int char_counter = 0;
time_t t = time(NULL);
struct tm *tm_info = localtime(&t);
if (flags & LOG_TIME_STAMP) {
printf("%02d:%02d:%02d - ", tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec);
} else {
printf(" ");
}
if (flags & LOG_LEVEL_WARN) {
if (flags & LOG_COLOR_OUT) {
printf(COLOR_YELLOW);
}
printf("[WARNING]: \t");
if (flags & LOG_COLOR_OUT) {
printf(COLOR_RESET);
}
} else if (flags & LOG_LEVEL_ERROR) {
if (flags & LOG_COLOR_OUT) {
printf(COLOR_RED);
}
printf("[ERROR]: \t");
if (flags & LOG_COLOR_OUT) {
printf(COLOR_RESET);
}
} else if (flags & LOG_LEVEL_INFO) {
if (flags & LOG_COLOR_OUT) {
printf(COLOR_BLUE);
}
printf("[INFO]: \t");
if (flags & LOG_COLOR_OUT) {
printf(COLOR_RESET);
}
} else if (flags & LOG_LEVEL_SUCCESS) {
if (flags & LOG_COLOR_OUT) {
printf(COLOR_GREEN);
}
printf("[SUCCESS]: \t");
if (flags & LOG_COLOR_OUT) {
printf(COLOR_RESET);
}
}
// Format string processing
while (*Format) {
if (*Format == '%') {
Format++;
switch (*Format) {
case 'd':
printf("%d", va_arg(args, int));
break;
case 'f':
printf("%f", va_arg(args, double));
break;
case 's':
printf("%s", va_arg(args, char *));
break;
case 'c':
printf("%c", va_arg(args, int));
break;
case 'x':
printf("%x", va_arg(args, unsigned int));
break;
case 'p':
printf("%p", va_arg(args, void *));
break;
case '%':
printf("%%");
break;
default:
printf("%%");
printf("%c", *Format);
break;
}
} else {
putchar(*Format);
}
Format++;
char_counter++;
}
putchar('\n'); // Optional newline
va_end(args);
return char_counter;
}

38
main/log.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef LOGGER_H_INCLUDED
#define LOGGER_H_INCLUDED
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _WIN32
#include <direct.h>
#include <windows.h>
#define MKDIR(path) _mkdir(path)
#else
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define MKDIR(path) mkdir(path, 0777)
#endif
#define LOG_LEVEL_INFO (1 << 0)
#define LOG_LEVEL_WARN (1 << 1)
#define LOG_LEVEL_ERROR (1 << 2)
#define LOG_LEVEL_SUCCESS (1 << 3)
#define LOG_COLOR_OUT (1 << 4)
#define LOG_ONLY_ERROR (1 << 5)
#define LOG_FILE (1 << 6)
#define LOG_TIME_STAMP (1 << 7)
#define COLOR_RED "\x1b[31m"
#define COLOR_GREEN "\x1b[32m"
#define COLOR_YELLOW "\x1b[33m"
#define COLOR_BLUE "\x1b[34m"
#define COLOR_RESET "\x1b[0m"
unsigned int flogf(unsigned short flags, const char *Format, ...);
#endif // LOGGER_H_INCLUDED

164
main/main.c Normal file
View File

@ -0,0 +1,164 @@
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include <string.h>
#include <stdio.h>
#include "./log.h"
const char *PROGRAM_NAME = "SMART_ADRESS";
const char *WIFI_NAME = "iPhone de Afonso";
const char *WIFI_PASSWORD = "afonsolindo22";
#define API_SOCKET_IP "172.20.10.2" // Change to your PC's IP
#define API_SOCKET_PORT 5005
#define GPS_UART_NUM UART_NUM_2
#define GPS_TX_PIN 17 // replace with your TX2 pin number
#define GPS_RX_PIN 16 // replace with your RX2 pin number
#define GPS_BUF_SIZE 1024
#define BUF_SIZE 128
#define LED_GPIO 2 // Onboard LED
#define WIFI_CONNECTED_BIT BIT0
// Event group to signal Wi-Fi connection
static EventGroupHandle_t s_wifi_event_group;
// INFO: Exit will just start the LED blink to show the user
// that the ESP-32 has reached the end
void stop() {
while (1) {
gpio_set_level(LED_GPIO, 1);
vTaskDelay(200 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 0);
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
void success() {
gpio_set_level(LED_GPIO, 1);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 0);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 1);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 0);
}
void error() {
gpio_set_level(LED_GPIO, 1);
vTaskDelay(700 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 0);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 1);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(LED_GPIO, 0);
}
void gps_init() {
const uart_config_t uart_config = {
.baud_rate = 9600, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
uart_param_config(GPS_UART_NUM, &uart_config);
uart_set_pin(GPS_UART_NUM, GPS_TX_PIN, GPS_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(GPS_UART_NUM, GPS_BUF_SIZE, 0, 0, NULL, 0);
}
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
flogf(LOG_LEVEL_WARN | LOG_COLOR_OUT | LOG_TIME_STAMP, "Retrying to connect...");
error();
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(const char *ssid, const char *pass) {
s_wifi_event_group = xEventGroupCreate();
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip);
wifi_config_t wifi_config = {0};
strncpy((char *)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
strncpy((char *)wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
esp_wifi_set_mode(WIFI_MODE_STA);
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
esp_wifi_start();
// Wait for connection
xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
flogf(LOG_LEVEL_SUCCESS | LOG_COLOR_OUT | LOG_TIME_STAMP, "Connected to the internet \"%s\"", ssid);
success();
}
void app_main(void) {
esp_rom_gpio_pad_select_gpio(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(LED_GPIO, 0);
flogf(LOG_LEVEL_INFO | LOG_COLOR_OUT | LOG_TIME_STAMP, "%s Starting", PROGRAM_NAME);
flogf(LOG_LEVEL_WARN | LOG_COLOR_OUT | LOG_TIME_STAMP, "Running NVS");
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
flogf(LOG_LEVEL_SUCCESS | LOG_COLOR_OUT | LOG_TIME_STAMP, "NVS OK!");
flogf(LOG_LEVEL_INFO | LOG_COLOR_OUT | LOG_TIME_STAMP, "Will now try to connect to \"%s\" with password [%s]", WIFI_NAME, WIFI_PASSWORD);
wifi_init_sta(WIFI_NAME, WIFI_PASSWORD);
flogf(LOG_LEVEL_INFO | LOG_COLOR_OUT | LOG_TIME_STAMP, "Inicializing UDP Socket to %s:%d", API_SOCKET_IP, API_SOCKET_PORT);
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock < 0) {
flogf(LOG_LEVEL_ERROR | LOG_COLOR_OUT | LOG_TIME_STAMP, "Failed to initialize socket!");
vTaskDelete(NULL);
return;
}
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(API_SOCKET_PORT);
dest_addr.sin_addr.s_addr = inet_addr(API_SOCKET_IP);
flogf(LOG_LEVEL_INFO | LOG_COLOR_OUT | LOG_TIME_STAMP, "Atempting to read GPS signals from PINS: TX%d and RX%d", GPS_TX_PIN, GPS_RX_PIN);
gps_init();
flogf(LOG_LEVEL_WARN | LOG_COLOR_OUT | LOG_TIME_STAMP, "Checking...");
flogf(LOG_LEVEL_INFO | LOG_COLOR_OUT | LOG_TIME_STAMP, "ESP Should start to send info to the open socket...");
uint8_t data[BUF_SIZE];
while (1) {
int len = uart_read_bytes(GPS_UART_NUM, data, BUF_SIZE, 100 / portTICK_PERIOD_MS);
if (len > 0) {
data[len] = '\0';
// INFO: THIS IS WHERE THE ESP SENDS STUFF TO THE LISTETNING PC
sendto(sock, data, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
success();
stop();
}

3688
sdkconfig Normal file

File diff suppressed because it is too large Load Diff

3027
sdkconfig.old Normal file

File diff suppressed because it is too large Load Diff