V 1.0 UDP Not working correctly...

This commit is contained in:
Ulysse Cura 2025-05-26 20:31:10 +02:00
parent e76f016f51
commit 5a3a02f546
11 changed files with 489 additions and 0 deletions

View File

@ -18,6 +18,8 @@ pico_sdk_init()
add_executable(controller add_executable(controller
src/main.c src/main.c
src/controller.c
src/inputs.c
src/wifi_operator.c src/wifi_operator.c
src/udp_server.c src/udp_server.c
) )

View File

@ -0,0 +1,73 @@
#include "include/controller.h"
#include <pico/stdio.h>
#include <pico/cyw43_arch.h>
#include <pico/mutex.h>
#include "include/wifi_operator.h"
#include "include/udp_server.h"
auto_init_mutex(wifi_mutex);
int controller_init(void)
{
stdio_init_all();
sleep_ms(1000);
inputs_init();
if(cyw43_arch_init())
{
return -1;
}
mutex_enter_blocking(&wifi_mutex);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
mutex_exit(&wifi_mutex);
wifi_operator_init_ap_mode();
udp_server_init();
controller.is_running = true;
}
static inline void update_time(void)
{
static bool led_state = false;
static double last_time = 0.0;
double start_time = (double)clock() * 1000.0 / (double)CLOCKS_PER_SEC;
controller.delta_time_ms = start_time - last_time;
last_time = start_time;
static double elapsed_time = 0.0;
elapsed_time += controller.delta_time_ms;
if(elapsed_time >= 1000)
{
elapsed_time = 0;
mutex_enter_blocking(&wifi_mutex);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state);
mutex_exit(&wifi_mutex);
led_state = !led_state;
}
}
void controller_handle_inputs_outputs(void)
{
update_time();
get_inputs();
mutex_enter_blocking(&wifi_mutex);
udp_server_send();
mutex_exit(&wifi_mutex);
tight_loop_contents();
}
void controller_deinit(void)
{
udp_server_exit();
}

View File

@ -0,0 +1,23 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <stdbool.h>
#include "inputs.h"
typedef struct controller_t {
inputs_buffer_t inputs_buffer;
double delta_time_ms;
bool is_running;
} controller_t;
extern controller_t controller;
// Init all controller's components
int controller_init(void);
// Handle all inputs and outputs
void controller_handle_inputs_outputs(void);
// Deinit controller's components
void controller_deinit(void);
#endif // CONTROLLER_H

View File

@ -0,0 +1,40 @@
#ifndef INPUTS_H
#define INPUTS_H
#include <pico/types.h>
typedef enum buttons_t {
BUTTON_L,
BUTTON_R,
BUTTON_BLACK,
BUTTON_BLUE,
BUTTON_WHITE,
BUTTON_GREEN,
NB_BUTTONS
} buttons_t;
typedef struct button_def_t {
uint pin;
} button_def_t;
extern const button_def_t BUTTONS_DEFS[];
#define JOYSTICK_X_AXIS_PIN 26
#define JOYSTICK_Y_AXIS_PIN 27
#define JOYSTICK_X_AXIS_ADC_INPUT 0
#define JOYSTICK_Y_AXIS_ADC_INPUT 1
typedef struct inputs_buffer_t {
int8_t x_axis_speed;
int8_t y_axis_speed;
bool buttons_states[NB_BUTTONS];
} inputs_buffer_t;
void inputs_init(void);
void get_inputs(void);
#endif // INPUTS_H

View File

@ -0,0 +1,97 @@
#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H
// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#ifndef MEM_SIZE
#define MEM_SIZE 32768 // Augmenté pour plus de mémoire disponible
#endif
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 32 // Augmenté pour réduire les allocations
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (16 * TCP_MSS) // Augmenté pour de meilleures performances
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS) // Augmenté pour de meilleures performances
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 0
#define LWIP_DHCP_SERVER 0
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0
#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF
#define SYS_LIGHTWEIGHT_PROT 1 // Protection pour le multicore
#define MEMP_NUM_PBUF 32 // Augmenté pour les buffers
#define ICMP_TTL 255 // Augmenté pour la fiabilité
#endif /* __LWIPOPTS_H__ */

View File

@ -0,0 +1,29 @@
#ifndef UDP_SERVER_H
#define UDP_SERVER_H
#include <stdint.h>
#include <lwip/udp.h>
#define UDP_SERVER_PORT 4242
#define UDP_SERVER_BUFFER_SIZE 16
#define UDP_PAYLOAD_ANGLE_L_BYTE 0x00
#define UDP_PAYLOAD_ANGLE_H_BYTE 0x01
#define UDP_PAYLOAD_X_AXIS_SPEED_BYTE 0x02
#define UDP_PAYLOAD_Y_AXIS_SPEED_BYTE 0x03
#define UDP_CLIENT_IP "192.168.128.2"
#define UDP_CLIENT_PORT 4243
typedef struct udp_server_t {
struct udp_pcb *pcb;
} udp_server_t;
void udp_server_init(void);
void udp_server_exit(void);
// Send data depending of the data in inputs buffer
void udp_server_send(void);
#endif // UDP_SERVER_H

View File

@ -0,0 +1,10 @@
#ifndef WIFI_OPERATOR_H
#define WIFI_OPERATOR_H
#define WIFI_OPERATOR_SSID "RiombotiqueAP"
#define WIFI_OPERATOR_PASSWORD "x4ptSLpPuJFcpzbLEhDoZ5J7dz"
#define WIFI_OPERATOR_CHANNEL 3
void wifi_operator_init_ap_mode(void);
#endif // WIFI_OPERATOR_H

View File

@ -0,0 +1,50 @@
#include "include/inputs.h"
#include <hardware/adc.h>
#include "include/controller.h"
#include <stdio.h>
const button_def_t BUTTONS_DEFS[NB_BUTTONS] = {
{13},
{9},
{1},
{5},
{6},
{2}
};
void inputs_init(void)
{
adc_init();
adc_gpio_init(JOYSTICK_X_AXIS_PIN);
adc_gpio_init(JOYSTICK_Y_AXIS_PIN);
for(buttons_t actual_button = BUTTON_L; actual_button < NB_BUTTONS; actual_button++)
{
const button_def_t *BUTTON_DEF = &BUTTONS_DEFS[actual_button];
gpio_init(BUTTON_DEF->pin);
gpio_set_dir(BUTTON_DEF->pin, GPIO_OUT);
gpio_pull_up(BUTTON_DEF->pin);
}
}
void get_inputs(void)
{
adc_select_input(JOYSTICK_X_AXIS_ADC_INPUT);
uint16_t joystick_x_axis = adc_read();
adc_select_input(JOYSTICK_Y_AXIS_ADC_INPUT);
uint16_t joystick_y_axis = adc_read();
controller.inputs_buffer.x_axis_speed = (joystick_x_axis / 16) - 128;
controller.inputs_buffer.y_axis_speed = (joystick_y_axis / 16) - 128;
for(buttons_t actual_button = BUTTON_L; actual_button < NB_BUTTONS; actual_button++)
{
const button_def_t *BUTTON_DEF = &BUTTONS_DEFS[actual_button];
controller.inputs_buffer.buttons_states[actual_button] = gpio_get(BUTTON_DEF->pin);
}
}

View File

@ -0,0 +1,17 @@
#include "include/controller.h"
controller_t controller;
int main(void)
{
if(controller_init()) return -1;
while(controller.is_running)
{
controller_handle_inputs_outputs();
}
controller_deinit();
return 0;
}

View File

@ -0,0 +1,98 @@
#include "udp_server.h"
#include <stdio.h>
#include <pico/cyw43_arch.h>
#include <lwip/def.h>
#include "include/controller.h"
udp_server_t udp_server;
void udp_server_init()
{
udp_server.pcb = udp_new();
if(!udp_server.pcb)
{
puts("Error creating UDP server");
return;
}
err_t err = udp_bind(udp_server.pcb, IP_ADDR_ANY, UDP_SERVER_PORT);
if(err != ERR_OK)
{
printf("Error binding UDP server: %d\n", err);
return;
}
}
void udp_server_exit(void)
{
if(udp_server.pcb)
{
udp_remove(udp_server.pcb);
udp_server.pcb = NULL;
}
}
static inline void udp_server_send_data(const uint8_t *data, size_t length)
{
ip4_addr_t remote_addr;
ip4addr_aton(UDP_CLIENT_IP, &remote_addr);
// Nombre maximum de tentatives
const int MAX_RETRIES = 3;
uint tries = 0;
while(tries < MAX_RETRIES)
{
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_RAM);
if(p == NULL)
{
printf("Try %d - Error allocating pbuf\n", ++tries);
sleep_ms(100); // Wait before retry
continue;
}
memcpy(p->payload, (char *)data, length);
err_t err = udp_sendto(udp_server.pcb, p, &remote_addr, UDP_CLIENT_PORT);
pbuf_free(p);
if (err == ERR_OK)
{
return; // Succès
}
else
{
const char* error_msg;
switch(err)
{
case ERR_MEM:
error_msg = "Insuficient memory";
break;
case ERR_BUF:
error_msg = "Buffer full";
break;
default:
error_msg = "Unknown error";
}
printf("Try %d - Error send UDP: %d (%s)\n", ++tries, err, error_msg);
sleep_ms(100); // Wait before retry
}
}
printf("Error sending data after %d tries...\n", tries);
}
void udp_server_send(void)
{
uint8_t data[UDP_SERVER_BUFFER_SIZE];
data[UDP_PAYLOAD_X_AXIS_SPEED_BYTE] = *(uint8_t *)&controller.inputs_buffer.x_axis_speed;
data[UDP_PAYLOAD_Y_AXIS_SPEED_BYTE] = *(uint8_t *)&controller.inputs_buffer.x_axis_speed;
udp_server_send_data(data, UDP_SERVER_BUFFER_SIZE);
}

View File

@ -0,0 +1,50 @@
#include "include/wifi_operator.h"
#include <pico/cyw43_arch.h>
#include <lwip/netif.h>
#include <lwip/ip4_addr.h>
void wifi_operator_init_ap_mode(void)
{
// Configuration IP pour le mode AP
ip4_addr_t ip, netmask, gateway;
IP4_ADDR(&ip, 192, 168, 128, 1);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gateway, 192, 168, 128, 1);
puts("Configuration WiFi en cours...");
// Désactiver le mode d'économie d'énergie
cyw43_wifi_pm(&cyw43_state, CYW43_NO_POWERSAVE_MODE);
// Activer le mode AP
cyw43_arch_enable_ap_mode(WIFI_OPERATOR_SSID, WIFI_OPERATOR_PASSWORD, CYW43_AUTH_WPA2_AES_PSK);
// Attendre que l'interface soit prête
int retry = 0;
while (netif_default == NULL && retry < 10)
{
sleep_ms(500);
retry++;
}
if (netif_default == NULL)
{
puts("Erreur: Interface réseau non initialisée");
return;
}
// Configuration du canal WiFi
cyw43_wifi_ap_set_channel(&cyw43_state, WIFI_OPERATOR_CHANNEL);
// Configuration de l'interface réseau
netif_set_up(netif_default);
netif_set_link_up(netif_default);
netif_set_addr(netif_default, &ip, &netmask, &gateway);
puts("Configuration IP terminée!");
puts("Point d'accès activé!");
printf("SSID:%s\n", WIFI_OPERATOR_SSID);
printf("Password:%s\n", WIFI_OPERATOR_PASSWORD);
printf("Channel:%d\n", WIFI_OPERATOR_CHANNEL);
}