barcode
This commit is contained in:
commit
2a38789890
|
@ -5,6 +5,7 @@ add_subdirectory(line_sensor)
|
||||||
add_subdirectory(car)
|
add_subdirectory(car)
|
||||||
add_subdirectory(ultrasonic_sensor)
|
add_subdirectory(ultrasonic_sensor)
|
||||||
add_subdirectory(magnetometer)
|
add_subdirectory(magnetometer)
|
||||||
|
add_subdirectory(frontend)
|
||||||
|
|
||||||
add_executable(rtos_car rtos_car.c)
|
add_executable(rtos_car rtos_car.c)
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ target_include_directories(rtos_car PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/motor
|
${CMAKE_CURRENT_LIST_DIR}/motor
|
||||||
${CMAKE_CURRENT_LIST_DIR}/line_sensor
|
${CMAKE_CURRENT_LIST_DIR}/line_sensor
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ultrasonic_sensor
|
${CMAKE_CURRENT_LIST_DIR}/ultrasonic_sensor
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/frontend
|
||||||
)
|
)
|
||||||
target_link_libraries(rtos_car
|
target_link_libraries(rtos_car
|
||||||
pico_cyw43_arch_lwip_sys_freertos
|
pico_cyw43_arch_lwip_sys_freertos
|
||||||
|
|
|
@ -10,6 +10,18 @@
|
||||||
#define ALPHA ( 0.01f ) // Complementary
|
#define ALPHA ( 0.01f ) // Complementary
|
||||||
// Filter Constant
|
// Filter Constant
|
||||||
|
|
||||||
|
// LSM303DLHC temperature compensation coefficients
|
||||||
|
#define SCALE_Z ( 1.0f ) // Scale for Z-axis
|
||||||
|
#define OFFSET_Z ( 3.0f ) // Offset for Z-axis
|
||||||
|
|
||||||
|
#define TEMPERATURE_OFFSET ( 25.0f ) // Reference
|
||||||
|
// temperature for
|
||||||
|
// calibration
|
||||||
|
|
||||||
|
#define TEMPERATURE_COEFFICIENT_Z ( 0.33f ) // Temperature
|
||||||
|
// coefficient for
|
||||||
|
// Z-axis
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The orientation of the car
|
* @brief The orientation of the car
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,42 +18,67 @@
|
||||||
#define DIRECTION_LEFT_FORWARD (1U << DIRECTION_PIN_LEFT_IN4)
|
#define DIRECTION_LEFT_FORWARD (1U << DIRECTION_PIN_LEFT_IN4)
|
||||||
#define DIRECTION_LEFT_BACKWARD (1U << DIRECTION_PIN_LEFT_IN3)
|
#define DIRECTION_LEFT_BACKWARD (1U << DIRECTION_PIN_LEFT_IN3)
|
||||||
|
|
||||||
|
#define DIRECTION_FORWARD (DIRECTION_RIGHT_FORWARD | DIRECTION_LEFT_FORWARD)
|
||||||
|
#define DIRECTION_BACKWARD (DIRECTION_RIGHT_BACKWARD | DIRECTION_LEFT_BACKWARD)
|
||||||
|
#define DIRECTION_LEFT (DIRECTION_RIGHT_FORWARD | DIRECTION_LEFT_BACKWARD)
|
||||||
|
#define DIRECTION_RIGHT (DIRECTION_RIGHT_BACKWARD | DIRECTION_LEFT_FORWARD)
|
||||||
|
|
||||||
#define SPEED_PIN_RIGHT 15U
|
#define SPEED_PIN_RIGHT 15U
|
||||||
#define SPEED_PIN_LEFT 16U
|
#define SPEED_PIN_LEFT 16U
|
||||||
|
|
||||||
#define PWM_CLK_DIV 250.f
|
#define PWM_CLK_DIV 250.f
|
||||||
#define PWM_WRAP 5000U
|
#define PWM_WRAP 5000U
|
||||||
|
|
||||||
/*
|
|
||||||
* ultimate gain Ku about 14, ultimate period Tu about 8 * 50 = 400ms
|
|
||||||
* Ku = 14, Tu = 400ms,
|
|
||||||
* Kp = 0.6 * Ku = 8.4
|
|
||||||
* Ki = Kp / Tu = 0.021
|
|
||||||
* Kd = Kp * Tu / 8 = 42
|
|
||||||
*/
|
|
||||||
#define PID_KP 8.4f
|
|
||||||
#define PID_KI 0.021f // 0.005f
|
|
||||||
#define PID_KD 42.f // 0.05f
|
|
||||||
|
|
||||||
#define MAX_SPEED 4900U
|
#define MAX_SPEED 4900U
|
||||||
#define MIN_SPEED 0U // To be changed
|
#define MIN_SPEED 0U // To be changed
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Structure for the motor speed
|
* @brief Structure for the motor speed parameters
|
||||||
* @param target_speed The target speed of the wheel, in cm/s
|
* @param target_speed_cms Target speed in cm/s
|
||||||
* @param pwm_level The pwm level of the wheel, from 0 to 5000
|
* @param current_speed_cms Current speed in cm/s
|
||||||
* @param sem The semaphore for the wheel
|
* @param distance_cm Distance travelled in cm
|
||||||
* @param p_slice_num The pointer to the slice number of the wheel
|
|
||||||
* @param channel The pwm channel of the wheel, left A or right B
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float target_speed_cms;
|
float current_cms;
|
||||||
float current_speed_cms;
|
float distance_cm;
|
||||||
uint16_t pwm_level;
|
|
||||||
SemaphoreHandle_t sem;
|
|
||||||
uint slice_num;
|
|
||||||
uint pwm_channel;
|
|
||||||
float distance;
|
|
||||||
} motor_speed_t;
|
} motor_speed_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Structure for the motor PWM parameters
|
||||||
|
* @param slice_num PWM slice number
|
||||||
|
* @param pwm_channel PWM channel, either A or B
|
||||||
|
* @param pwm_level PWM level, from 0 to 5000
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint slice_num;
|
||||||
|
uint channel;
|
||||||
|
uint16_t level;
|
||||||
|
} motor_pwm_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Structure for the motor PID parameters
|
||||||
|
* @param pid_kp Proportional gain
|
||||||
|
* @param pid_ki Integral gain
|
||||||
|
* @param pid_kd Derivative gain
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
float kp_value;
|
||||||
|
float ki_value;
|
||||||
|
float kd_value;
|
||||||
|
} motor_pid_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Structure for the motor parameters
|
||||||
|
* @param speed Motor speed parameters
|
||||||
|
* @param sem Semaphore for the motor speed
|
||||||
|
* @param pwm Motor PWM parameters
|
||||||
|
* @param pid Motor PID parameters
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
motor_speed_t speed;
|
||||||
|
SemaphoreHandle_t sem;
|
||||||
|
motor_pwm_t pwm;
|
||||||
|
motor_pid_t pid;
|
||||||
|
} motor_t;
|
||||||
|
|
||||||
#endif /* MOTOR_CONFIG_H */
|
#endif /* MOTOR_CONFIG_H */
|
|
@ -0,0 +1,39 @@
|
||||||
|
add_executable(
|
||||||
|
frontend
|
||||||
|
frontend.c
|
||||||
|
)
|
||||||
|
|
||||||
|
#message("Running makefsdata python script")
|
||||||
|
#execute_process(COMMAND
|
||||||
|
# py makefsdata.py
|
||||||
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
#)
|
||||||
|
|
||||||
|
message("Running makefsdata C script")
|
||||||
|
execute_process(COMMAND
|
||||||
|
gcc makefsdata.c -o makefsdata.exe
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
message("Generating htmldata.c")
|
||||||
|
execute_process(COMMAND
|
||||||
|
./makefsdata.exe
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
frontend
|
||||||
|
hardware_adc
|
||||||
|
pico_stdlib
|
||||||
|
#FreeRTOS-Kernel-Heap4 # FreeRTOS kernel and dynamic heap
|
||||||
|
pico_cyw43_arch_lwip_threadsafe_background
|
||||||
|
pico_lwip_http
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(frontend PRIVATE
|
||||||
|
#../config
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}../config
|
||||||
|
)
|
||||||
|
|
||||||
|
pico_enable_stdio_usb(frontend 1)
|
||||||
|
pico_add_extra_outputs(frontend)
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS V202111.00
|
||||||
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler Related */
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_TICKLESS_IDLE 0
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||||
|
#define configMAX_PRIORITIES 32
|
||||||
|
#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
|
||||||
|
/* Synchronization Related */
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
#define configUSE_TIME_SLICING 1
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
// todo need this for lwip FreeRTOS sys_arch to compile
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
|
||||||
|
|
||||||
|
/* System */
|
||||||
|
#define configSTACK_DEPTH_TYPE uint32_t
|
||||||
|
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||||
|
|
||||||
|
/* Memory allocation related definitions. */
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||||
|
#define configTOTAL_HEAP_SIZE (128*1024)
|
||||||
|
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_TRACE_FACILITY 1
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine related definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 1
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
|
#define configTIMER_QUEUE_LENGTH 10
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH 1024
|
||||||
|
|
||||||
|
/* Interrupt nesting behaviour configuration. */
|
||||||
|
/*
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
|
||||||
|
#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if FREE_RTOS_KERNEL_SMP // set by the RP2040 SMP port of FreeRTOS
|
||||||
|
/* SMP port only */
|
||||||
|
#define configNUM_CORES 1
|
||||||
|
#define configTICK_CORE 0
|
||||||
|
#define configRUN_MULTIPLE_PRIORITIES 1
|
||||||
|
#define configUSE_CORE_AFFINITY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* RP2040 specific */
|
||||||
|
#define configSUPPORT_PICO_SYNC_INTEROP 1
|
||||||
|
#define configSUPPORT_PICO_TIME_INTEROP 1
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
/* Define to trap errors during development. */
|
||||||
|
#define configASSERT(x) assert(x)
|
||||||
|
|
||||||
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
|
to exclude the API function. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 1
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||||
|
#define INCLUDE_eTaskGetState 1
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 1
|
||||||
|
#define INCLUDE_xTaskAbortDelay 1
|
||||||
|
#define INCLUDE_xTaskGetHandle 1
|
||||||
|
#define INCLUDE_xTaskResumeFromISR 1
|
||||||
|
#define INCLUDE_xQueueGetMutexHolder 1
|
||||||
|
|
||||||
|
/* A header file that defines trace macro can be included here. */
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include "lwip/apps/httpd.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
// CGI handler for start/stop car
|
||||||
|
const char * cgi_status_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
// Check if an request for LED has been made (/led.cgi?led=x)
|
||||||
|
// check if start/stop car button
|
||||||
|
if (strcmp(pcParam[0] , "status") == 0){
|
||||||
|
// Look at the argument to check if LED is to be turned on (x=1) or off (x=0)
|
||||||
|
if(strcmp(pcValue[0], "0") == 0){
|
||||||
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||||
|
printf("CAR STOP"); // call car stop func
|
||||||
|
}else if(strcmp(pcValue[0], "1") == 0){
|
||||||
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
||||||
|
printf("CAR START"); // call car start func
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the index page back to the user
|
||||||
|
return "/index.shtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
// CGI handler for speed control
|
||||||
|
const char * cgi_speed_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
// Check if an request for LED has been made (/led.cgi?led=x)
|
||||||
|
// check for speed increment/decrement control
|
||||||
|
if (strcmp(pcParam[0] , "speed") == 0){
|
||||||
|
if(strcmp(pcValue[0], "0") == 0){
|
||||||
|
printf("SPEED Decrease"); // call speed decrement
|
||||||
|
}else if(strcmp(pcValue[0], "1") == 0){
|
||||||
|
printf("Speed Increase"); // call speed increment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the index page back to the user
|
||||||
|
return "/index.shtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tCGI Struct
|
||||||
|
// Fill this with all of the CGI requests and their respective handlers
|
||||||
|
static const tCGI cgi_handlers[] = {
|
||||||
|
{
|
||||||
|
// Html request for "/status.cgi" triggers cgi_handler
|
||||||
|
"/status.cgi", cgi_status_handler
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Html request for "/speed.cgi" triggers cgi_handler
|
||||||
|
"/speed.cgi", cgi_speed_handler
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
void cgi_init(void)
|
||||||
|
{
|
||||||
|
http_set_cgi_handlers(cgi_handlers, 2);
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "lwip/apps/httpd.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include "lwipopts.h"
|
||||||
|
#include "ssi.h"
|
||||||
|
#include "cgi.h"
|
||||||
|
#include "lwip/inet.h"
|
||||||
|
//#include "FreeRTOS.h"
|
||||||
|
//#include "task.h"
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
|
||||||
|
// WIFI Credentials - take care if pushing to GitHub!
|
||||||
|
const char WIFI_SSID[] = "XXX";
|
||||||
|
const char WIFI_PASSWORD[] = "XXX";
|
||||||
|
|
||||||
|
void print_ip_address() {
|
||||||
|
struct netif *netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
if (netif_is_up(netif)) {
|
||||||
|
printf("IP Address: %s\n", ipaddr_ntoa(&(netif->ip_addr)));
|
||||||
|
}
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
cyw43_arch_init();
|
||||||
|
|
||||||
|
cyw43_arch_enable_sta_mode();
|
||||||
|
|
||||||
|
// Connect to the WiFI network - loop until connected
|
||||||
|
while(cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000) != 0){
|
||||||
|
printf("Attempting to connect...\n");
|
||||||
|
}
|
||||||
|
// Print a success message once connected
|
||||||
|
printf("Connected! \n");
|
||||||
|
|
||||||
|
// Print the assigned IP address
|
||||||
|
print_ip_address();
|
||||||
|
|
||||||
|
// Initialize web server
|
||||||
|
httpd_init();
|
||||||
|
printf("Http server initialized\n");
|
||||||
|
|
||||||
|
// Configure SSI and CGI handler
|
||||||
|
ssi_init();
|
||||||
|
printf("SSI Handler initialized\n");
|
||||||
|
cgi_init();
|
||||||
|
printf("CGI Handler initialized\n");
|
||||||
|
|
||||||
|
// Infinite loop
|
||||||
|
while(1);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
background-color: #0074d9;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speed {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speed-control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pid-output {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orientation-output {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maze-map {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Car Control Panel</h1>
|
||||||
|
<div class="container">
|
||||||
|
<div class="time">
|
||||||
|
<p id="elapsed-time">0 seconds</p>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="/status.cgi?status=1" ><button class="button" >Start</button></a>
|
||||||
|
|
||||||
|
<a href="/status.cgi?status=0" ><button class="button" >Stop</button></a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="speed">
|
||||||
|
<p>Speed: <!--#speed--></span></p>
|
||||||
|
<div class="speed-control">
|
||||||
|
<a href="/speed.cgi?speed=0" ><button class="button" >-</button></a>
|
||||||
|
<a href="/speed.cgi?speed=1" ><button class="button" >+</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="output">
|
||||||
|
<p>Barcode Scanner Output: <!--#barcode--></span></p>
|
||||||
|
</div>
|
||||||
|
<div class="pid-output">
|
||||||
|
<p>PID Controller Output: <!--#pid--></p>
|
||||||
|
</div>
|
||||||
|
<div class="orientation-output">
|
||||||
|
<p>Orientation: <!--#orient--></p>
|
||||||
|
</div>
|
||||||
|
<div class="maze-map" id="maze-map">
|
||||||
|
<!-- maze map part -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// Function to update and display elapsed time
|
||||||
|
function updateElapsedTime() {
|
||||||
|
// Check if the start time is stored in localStorage
|
||||||
|
let startTime = localStorage.getItem('startTime');
|
||||||
|
|
||||||
|
if (!startTime) {
|
||||||
|
// If no start time is stored, set the current time as the start time
|
||||||
|
startTime = Date.now();
|
||||||
|
localStorage.setItem('startTime', startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the elapsed time in seconds
|
||||||
|
const currentTime = Date.now();
|
||||||
|
const elapsedTime = Math.floor((currentTime - startTime) / 1000);
|
||||||
|
|
||||||
|
// Update the displayed elapsed time
|
||||||
|
document.getElementById('elapsed-time').textContent = `${elapsedTime} seconds`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the updateElapsedTime function when the page loads
|
||||||
|
window.onload = updateElapsedTime;
|
||||||
|
|
||||||
|
// Update the elapsed time every second
|
||||||
|
setInterval(updateElapsedTime, 1000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,384 @@
|
||||||
|
static const unsigned char data_index_shtml[] = {
|
||||||
|
/* ./index.shtml */
|
||||||
|
0x2F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x2E, 0x73, 0x68, 0x74, 0x6D, 0x6C, 0x00,
|
||||||
|
0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32,
|
||||||
|
0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72,
|
||||||
|
0x76, 0x65, 0x72, 0x3A, 0x20, 0x6C, 0x77, 0x49, 0x50, 0x2F,
|
||||||
|
0x70, 0x72, 0x65, 0x2D, 0x30, 0x2E, 0x36, 0x20, 0x28, 0x68,
|
||||||
|
0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E,
|
||||||
|
0x73, 0x69, 0x63, 0x73, 0x2E, 0x73, 0x65, 0x2F, 0x7E, 0x61,
|
||||||
|
0x64, 0x61, 0x6D, 0x2F, 0x6C, 0x77, 0x69, 0x70, 0x2F, 0x29,
|
||||||
|
0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D,
|
||||||
|
0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74,
|
||||||
|
0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A,
|
||||||
|
0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
|
||||||
|
0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, 0x3C, 0x68, 0x74,
|
||||||
|
0x6D, 0x6C, 0x3E, 0x0D, 0x0A, 0x3C, 0x68, 0x65, 0x61, 0x64,
|
||||||
|
0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74,
|
||||||
|
0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x7B,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66,
|
||||||
|
0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x41, 0x72, 0x69,
|
||||||
|
0x61, 0x6C, 0x2C, 0x20, 0x73, 0x61, 0x6E, 0x73, 0x2D, 0x73,
|
||||||
|
0x65, 0x72, 0x69, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74,
|
||||||
|
0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A,
|
||||||
|
0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D,
|
||||||
|
0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x68, 0x31, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
|
||||||
|
0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x33, 0x33, 0x33,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, 0x6E, 0x74, 0x61,
|
||||||
|
0x69, 0x6E, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66,
|
||||||
|
0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C,
|
||||||
|
0x65, 0x78, 0x2D, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
|
||||||
|
0x6F, 0x6E, 0x3A, 0x20, 0x63, 0x6F, 0x6C, 0x75, 0x6D, 0x6E,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E,
|
||||||
|
0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65,
|
||||||
|
0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62,
|
||||||
|
0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x7B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A,
|
||||||
|
0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F,
|
||||||
|
0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x63, 0x65, 0x6E,
|
||||||
|
0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61,
|
||||||
|
0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74,
|
||||||
|
0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D,
|
||||||
|
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x2E, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20,
|
||||||
|
0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
|
||||||
|
0x6E, 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x32,
|
||||||
|
0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F,
|
||||||
|
0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31,
|
||||||
|
0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61,
|
||||||
|
0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63,
|
||||||
|
0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x30, 0x30, 0x37,
|
||||||
|
0x34, 0x64, 0x39, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F,
|
||||||
|
0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65,
|
||||||
|
0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20,
|
||||||
|
0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D,
|
||||||
|
0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x2E, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x7B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69,
|
||||||
|
0x7A, 0x65, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D,
|
||||||
|
0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x2E, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2D,
|
||||||
|
0x63, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x20, 0x7B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79,
|
||||||
|
0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65,
|
||||||
|
0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x69,
|
||||||
|
0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74,
|
||||||
|
0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D,
|
||||||
|
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x2E, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20,
|
||||||
|
0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D,
|
||||||
|
0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69,
|
||||||
|
0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70,
|
||||||
|
0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x70, 0x69, 0x64, 0x2D,
|
||||||
|
0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A,
|
||||||
|
0x65, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74,
|
||||||
|
0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D,
|
||||||
|
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x2E, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x61,
|
||||||
|
0x74, 0x69, 0x6F, 0x6E, 0x2D, 0x6F, 0x75, 0x74, 0x70, 0x75,
|
||||||
|
0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E,
|
||||||
|
0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x34,
|
||||||
|
0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72,
|
||||||
|
0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32,
|
||||||
|
0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x6D, 0x61,
|
||||||
|
0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x20, 0x7B, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74,
|
||||||
|
0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20,
|
||||||
|
0x32, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x32, 0x30,
|
||||||
|
0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F,
|
||||||
|
0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x20,
|
||||||
|
0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x33, 0x33, 0x33,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
|
||||||
|
0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F,
|
||||||
|
0x68, 0x65, 0x61, 0x64, 0x3E, 0x0D, 0x0A, 0x3C, 0x62, 0x6F,
|
||||||
|
0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C,
|
||||||
|
0x68, 0x31, 0x3E, 0x43, 0x61, 0x72, 0x20, 0x43, 0x6F, 0x6E,
|
||||||
|
0x74, 0x72, 0x6F, 0x6C, 0x20, 0x50, 0x61, 0x6E, 0x65, 0x6C,
|
||||||
|
0x3C, 0x2F, 0x68, 0x31, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73,
|
||||||
|
0x73, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E,
|
||||||
|
0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63,
|
||||||
|
0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x69, 0x6D, 0x65,
|
||||||
|
0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x20, 0x69,
|
||||||
|
0x64, 0x3D, 0x22, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64,
|
||||||
|
0x2D, 0x74, 0x69, 0x6D, 0x65, 0x22, 0x3E, 0x30, 0x20, 0x73,
|
||||||
|
0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x3C, 0x2F, 0x70, 0x3E,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76,
|
||||||
|
0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75,
|
||||||
|
0x74, 0x74, 0x6F, 0x6E, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22,
|
||||||
|
0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2E, 0x63, 0x67,
|
||||||
|
0x69, 0x3F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3D, 0x31,
|
||||||
|
0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E,
|
||||||
|
0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75,
|
||||||
|
0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x53, 0x74, 0x61,
|
||||||
|
0x72, 0x74, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E,
|
||||||
|
0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
|
||||||
|
0x3D, 0x22, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2E,
|
||||||
|
0x63, 0x67, 0x69, 0x3F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||||
|
0x3D, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74,
|
||||||
|
0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22,
|
||||||
|
0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x53,
|
||||||
|
0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F,
|
||||||
|
0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69,
|
||||||
|
0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61,
|
||||||
|
0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22,
|
||||||
|
0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x53, 0x70,
|
||||||
|
0x65, 0x65, 0x64, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23,
|
||||||
|
0x73, 0x70, 0x65, 0x65, 0x64, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F,
|
||||||
|
0x73, 0x70, 0x61, 0x6E, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C,
|
||||||
|
0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, 0x65, 0x64,
|
||||||
|
0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x22, 0x3E,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
|
||||||
|
0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x70,
|
||||||
|
0x65, 0x65, 0x64, 0x2E, 0x63, 0x67, 0x69, 0x3F, 0x73, 0x70,
|
||||||
|
0x65, 0x65, 0x64, 0x3D, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62,
|
||||||
|
0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73,
|
||||||
|
0x73, 0x3D, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22,
|
||||||
|
0x20, 0x3E, 0x2D, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F,
|
||||||
|
0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65,
|
||||||
|
0x66, 0x3D, 0x22, 0x2F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2E,
|
||||||
|
0x63, 0x67, 0x69, 0x3F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3D,
|
||||||
|
0x31, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F,
|
||||||
|
0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62,
|
||||||
|
0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x2B, 0x3C,
|
||||||
|
0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F,
|
||||||
|
0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69,
|
||||||
|
0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64,
|
||||||
|
0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22,
|
||||||
|
0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x70, 0x3E, 0x42, 0x61, 0x72, 0x63, 0x6F,
|
||||||
|
0x64, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x6E, 0x65, 0x72,
|
||||||
|
0x20, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3A, 0x20, 0x3C,
|
||||||
|
0x21, 0x2D, 0x2D, 0x23, 0x62, 0x61, 0x72, 0x63, 0x6F, 0x64,
|
||||||
|
0x65, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E,
|
||||||
|
0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76,
|
||||||
|
0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73,
|
||||||
|
0x73, 0x3D, 0x22, 0x70, 0x69, 0x64, 0x2D, 0x6F, 0x75, 0x74,
|
||||||
|
0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
|
||||||
|
0x70, 0x3E, 0x50, 0x49, 0x44, 0x20, 0x43, 0x6F, 0x6E, 0x74,
|
||||||
|
0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x72, 0x20, 0x4F, 0x75, 0x74,
|
||||||
|
0x70, 0x75, 0x74, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23,
|
||||||
|
0x70, 0x69, 0x64, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x70, 0x3E,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76,
|
||||||
|
0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x6F, 0x72,
|
||||||
|
0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2D,
|
||||||
|
0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x70, 0x3E, 0x4F, 0x72, 0x69, 0x65, 0x6E,
|
||||||
|
0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x3C, 0x21,
|
||||||
|
0x2D, 0x2D, 0x23, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x2D,
|
||||||
|
0x2D, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69,
|
||||||
|
0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61,
|
||||||
|
0x73, 0x73, 0x3D, 0x22, 0x6D, 0x61, 0x7A, 0x65, 0x2D, 0x6D,
|
||||||
|
0x61, 0x70, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x6D, 0x61,
|
||||||
|
0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x22, 0x3E, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x6D, 0x61, 0x7A,
|
||||||
|
0x65, 0x20, 0x6D, 0x61, 0x70, 0x20, 0x70, 0x61, 0x72, 0x74,
|
||||||
|
0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E,
|
||||||
|
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69,
|
||||||
|
0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73,
|
||||||
|
0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46,
|
||||||
|
0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F,
|
||||||
|
0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6E,
|
||||||
|
0x64, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20,
|
||||||
|
0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69,
|
||||||
|
0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E,
|
||||||
|
0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61,
|
||||||
|
0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x28, 0x29,
|
||||||
|
0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43,
|
||||||
|
0x68, 0x65, 0x63, 0x6B, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69,
|
||||||
|
0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x6F, 0x72,
|
||||||
|
0x65, 0x64, 0x20, 0x69, 0x6E, 0x20, 0x6C, 0x6F, 0x63, 0x61,
|
||||||
|
0x6C, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72,
|
||||||
|
0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x6C, 0x6F,
|
||||||
|
0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65,
|
||||||
|
0x2E, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6D, 0x28, 0x27,
|
||||||
|
0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x27,
|
||||||
|
0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
|
||||||
|
0x20, 0x28, 0x21, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69,
|
||||||
|
0x6D, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x49, 0x66, 0x20, 0x6E,
|
||||||
|
0x6F, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69,
|
||||||
|
0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x6F, 0x72,
|
||||||
|
0x65, 0x64, 0x2C, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20,
|
||||||
|
0x74, 0x69, 0x6D, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69,
|
||||||
|
0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20,
|
||||||
|
0x3D, 0x20, 0x44, 0x61, 0x74, 0x65, 0x2E, 0x6E, 0x6F, 0x77,
|
||||||
|
0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, 0x72,
|
||||||
|
0x61, 0x67, 0x65, 0x2E, 0x73, 0x65, 0x74, 0x49, 0x74, 0x65,
|
||||||
|
0x6D, 0x28, 0x27, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69,
|
||||||
|
0x6D, 0x65, 0x27, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74,
|
||||||
|
0x54, 0x69, 0x6D, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20,
|
||||||
|
0x43, 0x61, 0x6C, 0x63, 0x75, 0x6C, 0x61, 0x74, 0x65, 0x20,
|
||||||
|
0x74, 0x68, 0x65, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65,
|
||||||
|
0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x69, 0x6E, 0x20,
|
||||||
|
0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x0D, 0x0A, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x75, 0x72,
|
||||||
|
0x72, 0x65, 0x6E, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x3D,
|
||||||
|
0x20, 0x44, 0x61, 0x74, 0x65, 0x2E, 0x6E, 0x6F, 0x77, 0x28,
|
||||||
|
0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73,
|
||||||
|
0x74, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54,
|
||||||
|
0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x4D, 0x61, 0x74, 0x68,
|
||||||
|
0x2E, 0x66, 0x6C, 0x6F, 0x6F, 0x72, 0x28, 0x28, 0x63, 0x75,
|
||||||
|
0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20,
|
||||||
|
0x2D, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D,
|
||||||
|
0x65, 0x29, 0x20, 0x2F, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20,
|
||||||
|
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65,
|
||||||
|
0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x64,
|
||||||
|
0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74,
|
||||||
|
0x69, 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63,
|
||||||
|
0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45,
|
||||||
|
0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64,
|
||||||
|
0x28, 0x27, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x2D,
|
||||||
|
0x74, 0x69, 0x6D, 0x65, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78,
|
||||||
|
0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D,
|
||||||
|
0x20, 0x60, 0x24, 0x7B, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65,
|
||||||
|
0x64, 0x54, 0x69, 0x6D, 0x65, 0x7D, 0x20, 0x73, 0x65, 0x63,
|
||||||
|
0x6F, 0x6E, 0x64, 0x73, 0x60, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F,
|
||||||
|
0x2F, 0x20, 0x43, 0x61, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65,
|
||||||
|
0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61,
|
||||||
|
0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x66,
|
||||||
|
0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x68,
|
||||||
|
0x65, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x67,
|
||||||
|
0x65, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x73, 0x0D, 0x0A, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6E,
|
||||||
|
0x64, 0x6F, 0x77, 0x2E, 0x6F, 0x6E, 0x6C, 0x6F, 0x61, 0x64,
|
||||||
|
0x20, 0x3D, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45,
|
||||||
|
0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65,
|
||||||
|
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x70, 0x64, 0x61,
|
||||||
|
0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6C, 0x61,
|
||||||
|
0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
|
||||||
|
0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x73, 0x65, 0x63, 0x6F,
|
||||||
|
0x6E, 0x64, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6E, 0x74, 0x65, 0x72,
|
||||||
|
0x76, 0x61, 0x6C, 0x28, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||||
|
0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D,
|
||||||
|
0x65, 0x2C, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D,
|
||||||
|
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
|
||||||
|
0x2F, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
|
||||||
|
0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x68,
|
||||||
|
0x74, 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, };
|
||||||
|
|
||||||
|
const struct fsdata_file file_index_shtml[] = {{ NULL, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13, FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT }};
|
||||||
|
|
||||||
|
#define FS_ROOT file_index_shtml
|
||||||
|
#define FS_NUMFILES 1
|
|
@ -0,0 +1,93 @@
|
||||||
|
// 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
|
||||||
|
#define MEM_SIZE 4000
|
||||||
|
#define MEMP_NUM_TCP_SEG 32
|
||||||
|
#define MEMP_NUM_ARP_QUEUE 10
|
||||||
|
#define PBUF_POOL_SIZE 24
|
||||||
|
#define LWIP_ARP 1
|
||||||
|
#define LWIP_ETHERNET 1
|
||||||
|
#define LWIP_ICMP 1
|
||||||
|
#define LWIP_RAW 1
|
||||||
|
#define TCP_WND (8 * TCP_MSS)
|
||||||
|
#define TCP_MSS 1460
|
||||||
|
#define TCP_SND_BUF (8 * TCP_MSS)
|
||||||
|
#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 1
|
||||||
|
#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
|
||||||
|
|
||||||
|
// This section enables HTTPD server with SSI, SGI
|
||||||
|
// and tells server which converted HTML files to use
|
||||||
|
#define LWIP_HTTPD 1
|
||||||
|
#define LWIP_HTTPD_SSI 1
|
||||||
|
#define LWIP_HTTPD_CGI 1
|
||||||
|
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
|
||||||
|
#define HTTPD_FSDATA_FILE "htmldata.c"
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Function to encode a string to hexadecimal
|
||||||
|
void stringToHex(const char* input, char* file, int length) {
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
sprintf(file + 2 * i, "%02X", input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FILE *file;
|
||||||
|
file = fopen("htmldata.c", "w");
|
||||||
|
const char *folder[] = {
|
||||||
|
//Add your file path here
|
||||||
|
"./html_files/index.shtml"
|
||||||
|
};
|
||||||
|
const char *files[] = {
|
||||||
|
"./index.shtml"
|
||||||
|
};
|
||||||
|
char *varnames[100] = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int fileCount = sizeof(files)/sizeof(files[0]);
|
||||||
|
for(int i = 0; i< fileCount ;i++){
|
||||||
|
char header[1024];
|
||||||
|
char fvar[256];
|
||||||
|
if (strstr(files[i], "404")) {
|
||||||
|
snprintf(header, sizeof(header), "HTTP/1.0 404 File not found\r\n");
|
||||||
|
} else {
|
||||||
|
snprintf(header, sizeof(header), "HTTP/1.0 200 OK\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header),
|
||||||
|
"Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
|
||||||
|
|
||||||
|
// Add content-type based on files extension
|
||||||
|
if (strstr(files[i], ".html") || strstr(files[i], ".shtml")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: text/html\r\n");
|
||||||
|
} else if (strstr(files[i], ".jpg")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: image/jpeg\r\n");
|
||||||
|
} else if (strstr(files[i], ".gif")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: image/gif\r\n");
|
||||||
|
} else if (strstr(files[i], ".png")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: image/png\r\n");
|
||||||
|
} else if (strstr(files[i], ".class")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: application/octet-stream\r\n");
|
||||||
|
} else if (strstr(files[i], ".js")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: text/javascript\r\n");
|
||||||
|
} else if (strstr(files[i], ".css")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: text/css\r\n");
|
||||||
|
} else if (strstr(files[i], ".svg")) {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: image/svg+xml\r\n");
|
||||||
|
} else {
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "Content-type: text/plain\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(header + strlen(header), sizeof(header) - strlen(header), "\r\n");
|
||||||
|
|
||||||
|
// Create a variable name for the files[i]
|
||||||
|
strcpy(fvar, files[i] + 1); // Remove the leading dot in the filename
|
||||||
|
for (int j = 0; fvar[j]; j++) {
|
||||||
|
if (fvar[j] == '/' || fvar[j] == '\\') {
|
||||||
|
fvar[j] = '_';
|
||||||
|
} else if (fvar[j] == '.') {
|
||||||
|
fvar[j] = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "static const unsigned char data%s[] = {\n", fvar);
|
||||||
|
fprintf(file, "\t/* %s */\n\t", files[i]);
|
||||||
|
|
||||||
|
// Encode the filename as hexadecimal
|
||||||
|
char hexFileName[2 * strlen(files[i]) + 1];
|
||||||
|
stringToHex(files[i] + 1, hexFileName, strlen(files[i]) - 1);
|
||||||
|
int count = 0;
|
||||||
|
for (int j = 0; hexFileName[j]; j++) {
|
||||||
|
fprintf(file, "0x%c%c, ", hexFileName[j], hexFileName[j + 1]);
|
||||||
|
j++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
fprintf(file, "0x00,\n\t");
|
||||||
|
|
||||||
|
// Encode the HTTP header as hexadecimal
|
||||||
|
char hexHeader[2 * strlen(header) + 1];
|
||||||
|
stringToHex(header, hexHeader, strlen(header));
|
||||||
|
count = 0;
|
||||||
|
for (int j = 0; hexHeader[j]; j++) {
|
||||||
|
fprintf(file, "0x%c%c, ", hexHeader[j], hexHeader[j + 1]);
|
||||||
|
j++;
|
||||||
|
count++;
|
||||||
|
if (count == 10) {
|
||||||
|
fprintf(file, "\n\t");
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(file, "\n\t");
|
||||||
|
// Encode the file content as hexadecimal
|
||||||
|
FILE* filePtr = fopen(folder[i], "rb");
|
||||||
|
count = 0;
|
||||||
|
if (filePtr) {
|
||||||
|
int ch;
|
||||||
|
while ((ch = fgetc(filePtr)) != EOF) {
|
||||||
|
fprintf(file, "0x%02X, ", ch);
|
||||||
|
count++;
|
||||||
|
if (count == 10) {
|
||||||
|
fprintf(file, "\n\t");
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(filePtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "};\n\n");
|
||||||
|
varnames[i] = malloc(strlen(fvar) + 1);
|
||||||
|
strcpy(varnames[i], fvar);
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(file, "const struct fsdata_file file%s[] = {{ %s, data%s, data%s + %d, sizeof(data%s) - %d, FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT }};\n",
|
||||||
|
fvar,"NULL", fvar, fvar, strlen(files[i]) , fvar, strlen(files[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "\n#define FS_ROOT file%s\n",varnames[fileCount - 1] );
|
||||||
|
fprintf(file, "#define FS_NUMFILES %d\n", fileCount);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# This script is by @rspeir on GitHub:
|
||||||
|
# https://github.com/krzmaz/pico-w-webserver-example/pull/1/files/4b3e78351dd236f213da9bebbb20df690d470476#diff-e675c4a367e382db6f9ba61833a58c62029d8c71c3156a9f238b612b69de279d
|
||||||
|
# Renamed output to avoid linking incorrect file
|
||||||
|
|
||||||
|
import os
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
#Create file to write output into
|
||||||
|
output = open('htmldata.c', 'w')
|
||||||
|
|
||||||
|
#Traverse directory, generate list of files
|
||||||
|
files = list()
|
||||||
|
os.chdir('./html_files')
|
||||||
|
for(dirpath, dirnames, filenames) in os.walk('.'):
|
||||||
|
files += [os.path.join(dirpath, file) for file in filenames]
|
||||||
|
|
||||||
|
filenames = list()
|
||||||
|
varnames = list()
|
||||||
|
|
||||||
|
#Generate appropriate HTTP headers
|
||||||
|
for file in files:
|
||||||
|
|
||||||
|
if '404' in file:
|
||||||
|
header = "HTTP/1.0 404 File not found\r\n"
|
||||||
|
else:
|
||||||
|
header = "HTTP/1.0 200 OK\r\n"
|
||||||
|
|
||||||
|
header += "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"
|
||||||
|
|
||||||
|
if '.html' in file:
|
||||||
|
header += "Content-type: text/html\r\n"
|
||||||
|
elif '.shtml' in file:
|
||||||
|
header += "Content-type: text/html\r\n"
|
||||||
|
elif '.jpg' in file:
|
||||||
|
header += "Content-type: image/jpeg\r\n"
|
||||||
|
elif '.gif' in file:
|
||||||
|
header += "Content-type: image/gif\r\n"
|
||||||
|
elif '.png' in file:
|
||||||
|
header += "Content-type: image/png\r\n"
|
||||||
|
elif '.class' in file:
|
||||||
|
header += "Content-type: application/octet-stream\r\n"
|
||||||
|
elif '.js' in file:
|
||||||
|
header += "Content-type: text/javascript\r\n"
|
||||||
|
elif '.css' in file:
|
||||||
|
header += "Content-type: text/css\r\n"
|
||||||
|
elif '.svg' in file:
|
||||||
|
header += "Content-type: image/svg+xml\r\n"
|
||||||
|
else:
|
||||||
|
header += "Content-type: text/plain\r\n"
|
||||||
|
|
||||||
|
header += "\r\n"
|
||||||
|
|
||||||
|
fvar = file[1:] #remove leading dot in filename
|
||||||
|
fvar = fvar.replace('/', '_') #replace *nix path separator with underscore
|
||||||
|
fvar = fvar.replace('\\', '_') #replace DOS path separator with underscore
|
||||||
|
fvar = fvar.replace('.', '_') #replace file extension dot with underscore
|
||||||
|
|
||||||
|
output.write("static const unsigned char data{}[] = {{\n".format(fvar))
|
||||||
|
output.write("\t/* {} */\n\t".format(file))
|
||||||
|
|
||||||
|
#first set of hex data encodes the filename
|
||||||
|
b = bytes(file[1:].replace('\\', '/'), 'utf-8') #change DOS path separator to forward slash
|
||||||
|
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||||
|
output.write("0x{}, ".format(byte.decode()))
|
||||||
|
output.write("0,\n\t")
|
||||||
|
|
||||||
|
#second set of hex data is the HTTP header/mime type we generated above
|
||||||
|
b = bytes(header, 'utf-8')
|
||||||
|
count = 0
|
||||||
|
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||||
|
output.write("0x{}, ".format(byte.decode()))
|
||||||
|
count = count + 1
|
||||||
|
if(count == 10):
|
||||||
|
output.write("\n\t")
|
||||||
|
count = 0
|
||||||
|
output.write("\n\t")
|
||||||
|
|
||||||
|
#finally, dump raw hex data from files
|
||||||
|
with open(file, 'rb') as f:
|
||||||
|
count = 0
|
||||||
|
while(byte := f.read(1)):
|
||||||
|
byte = binascii.hexlify(byte)
|
||||||
|
output.write("0x{}, ".format(byte.decode()))
|
||||||
|
count = count + 1
|
||||||
|
if(count == 10):
|
||||||
|
output.write("\n\t")
|
||||||
|
count = 0
|
||||||
|
output.write("};\n\n")
|
||||||
|
|
||||||
|
filenames.append(file[1:])
|
||||||
|
varnames.append(fvar)
|
||||||
|
|
||||||
|
for i in range(len(filenames)):
|
||||||
|
prevfile = "NULL"
|
||||||
|
if(i > 0):
|
||||||
|
prevfile = "file" + varnames[i-1]
|
||||||
|
|
||||||
|
output.write("const struct fsdata_file file{0}[] = {{{{ {1}, data{2}, ".format(varnames[i], prevfile, varnames[i]))
|
||||||
|
output.write("data{} + {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||||
|
output.write("sizeof(data{}) - {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||||
|
output.write("FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT}};\n")
|
||||||
|
|
||||||
|
output.write("\n#define FS_ROOT file{}\n".format(varnames[-1]))
|
||||||
|
output.write("#define FS_NUMFILES {}\n".format(len(filenames)))
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "lwip/apps/httpd.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include "hardware/adc.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
// SSI tags - tag length limited to 8 bytes by default
|
||||||
|
const char * ssi_tags[] = {"speed","barcode","pid","orient"};
|
||||||
|
|
||||||
|
u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
|
||||||
|
size_t printed;
|
||||||
|
switch (iIndex) {
|
||||||
|
case 0: // Speed
|
||||||
|
{
|
||||||
|
// call getSpeed() function
|
||||||
|
const float Speed = adc_read() * 3.3f / (1 << 12);
|
||||||
|
printed = snprintf(pcInsert, iInsertLen, "%f ",Speed);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // barcode
|
||||||
|
{
|
||||||
|
// call getBarcodeOutput() function
|
||||||
|
const char* barC = "36" ;
|
||||||
|
printed = snprintf(pcInsert, iInsertLen, "%s", barC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //PID
|
||||||
|
{
|
||||||
|
// whatever to display for PID
|
||||||
|
const char* PID = "54" ;
|
||||||
|
printed = snprintf(pcInsert, iInsertLen, "%s", PID);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: //Orientation
|
||||||
|
{
|
||||||
|
// call getOrientation() function
|
||||||
|
const char* orien = "South" ;
|
||||||
|
printed = snprintf(pcInsert, iInsertLen, "%s", orien);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printed = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (u16_t)printed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the SSI handler
|
||||||
|
void ssi_init() {
|
||||||
|
// Initialise ADC (internal pin)
|
||||||
|
adc_init();
|
||||||
|
adc_set_temp_sensor_enabled(true);
|
||||||
|
adc_select_input(4);
|
||||||
|
|
||||||
|
http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags));
|
||||||
|
}
|
|
@ -15,13 +15,34 @@
|
||||||
*
|
*
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
|
//void
|
||||||
|
//monitor_left_sensor_task(__unused void *params) {
|
||||||
|
// for (;;)
|
||||||
|
// {
|
||||||
|
// if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE)
|
||||||
|
// {
|
||||||
|
// if (left_sensor_triggered == pdTRUE)
|
||||||
|
// {
|
||||||
|
// printf("left sensor triggered\n");
|
||||||
|
// // Get Current State
|
||||||
|
// state_t state = gpio_get(LEFT_SENSOR_PIN);
|
||||||
|
//
|
||||||
|
// xMessageBufferSend(left_sensor_msg_buffer,
|
||||||
|
// &state,
|
||||||
|
// sizeof(state_t),
|
||||||
|
// 0);
|
||||||
|
// // Reset the flag
|
||||||
|
// left_sensor_triggered = pdFALSE;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
void
|
void
|
||||||
monitor_left_sensor_task(__unused void *params) {
|
monitor_left_sensor_task(__unused void *params) {
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE)
|
if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE)
|
||||||
{
|
|
||||||
if (left_sensor_triggered == pdTRUE)
|
|
||||||
{
|
{
|
||||||
printf("left sensor triggered\n");
|
printf("left sensor triggered\n");
|
||||||
// Get Current State
|
// Get Current State
|
||||||
|
@ -31,9 +52,6 @@ monitor_left_sensor_task(__unused void *params) {
|
||||||
&state,
|
&state,
|
||||||
sizeof(state_t),
|
sizeof(state_t),
|
||||||
0);
|
0);
|
||||||
// Reset the flag
|
|
||||||
left_sensor_triggered = pdFALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,12 +64,32 @@ monitor_left_sensor_task(__unused void *params) {
|
||||||
*
|
*
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
|
//void
|
||||||
|
//monitor_right_sensor_task(void *params) {
|
||||||
|
// for (;;) {
|
||||||
|
// if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) {
|
||||||
|
// // Check the flag or receive the message
|
||||||
|
// if (right_sensor_triggered == pdTRUE) {
|
||||||
|
// printf("right sensor triggered\n");
|
||||||
|
// // Get Current State
|
||||||
|
// state_t state = gpio_get(RIGHT_SENSOR_PIN);
|
||||||
|
//
|
||||||
|
// xMessageBufferSend(right_sensor_msg_buffer,
|
||||||
|
// &state,
|
||||||
|
// sizeof(state_t),
|
||||||
|
// 0);
|
||||||
|
// // Reset the flag
|
||||||
|
// right_sensor_triggered = pdFALSE;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
void
|
void
|
||||||
monitor_right_sensor_task(void *params) {
|
monitor_right_sensor_task(void *params) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) {
|
||||||
// Check the flag or receive the message
|
// Check the flag or receive the message
|
||||||
if (right_sensor_triggered == pdTRUE) {
|
|
||||||
printf("right sensor triggered\n");
|
printf("right sensor triggered\n");
|
||||||
// Get Current State
|
// Get Current State
|
||||||
state_t state = gpio_get(RIGHT_SENSOR_PIN);
|
state_t state = gpio_get(RIGHT_SENSOR_PIN);
|
||||||
|
@ -60,9 +98,6 @@ monitor_right_sensor_task(void *params) {
|
||||||
&state,
|
&state,
|
||||||
sizeof(state_t),
|
sizeof(state_t),
|
||||||
0);
|
0);
|
||||||
// Reset the flag
|
|
||||||
right_sensor_triggered = pdFALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,17 @@ launch()
|
||||||
|
|
||||||
irq_set_enabled(IO_IRQ_BANK0, true);
|
irq_set_enabled(IO_IRQ_BANK0, true);
|
||||||
|
|
||||||
// struct repeating_timer g_left_sensor_timer;
|
struct repeating_timer g_left_sensor_timer;
|
||||||
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||||
// h_left_sensor_timer_handler,
|
h_left_sensor_timer_handler,
|
||||||
// NULL,
|
NULL,
|
||||||
// &g_left_sensor_timer);
|
&g_left_sensor_timer);
|
||||||
//
|
|
||||||
// struct repeating_timer g_right_sensor_timer;
|
struct repeating_timer g_right_sensor_timer;
|
||||||
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||||
// h_right_sensor_timer_handler,
|
h_right_sensor_timer_handler,
|
||||||
// NULL,
|
NULL,
|
||||||
// &g_right_sensor_timer);
|
&g_right_sensor_timer);
|
||||||
|
|
||||||
TaskHandle_t h_monitor_left_sensor_task;
|
TaskHandle_t h_monitor_left_sensor_task;
|
||||||
xTaskCreate(monitor_left_sensor_task,
|
xTaskCreate(monitor_left_sensor_task,
|
||||||
|
|
|
@ -28,15 +28,7 @@
|
||||||
#define LSM303_TEMP_OUT_H_M 0x31
|
#define LSM303_TEMP_OUT_H_M 0x31
|
||||||
#define LSM303_TEMP_OUT_L_M 0x32
|
#define LSM303_TEMP_OUT_L_M 0x32
|
||||||
|
|
||||||
// LSM303DLHC temperature compensation coefficients
|
|
||||||
#define SCALE_Z 0.9 // Scale factor for Z-axis
|
|
||||||
#define OFFSET_Z 5.0 // Offset for Z-axis
|
|
||||||
|
|
||||||
#define TEMPERATURE_OFFSET 25.0 // Reference temperature for calibration
|
|
||||||
#define TEMPERATURE_COEFFICIENT_Z 0.33
|
|
||||||
|
|
||||||
#define OFFSET_Z 5.0
|
|
||||||
#define SCALE_Z 0.9
|
|
||||||
|
|
||||||
#define ACCEL_ADDR 0x19
|
#define ACCEL_ADDR 0x19
|
||||||
#define MAG_ADDR 0x1E
|
#define MAG_ADDR 0x1E
|
||||||
|
|
|
@ -6,15 +6,13 @@
|
||||||
*
|
*
|
||||||
* @details The direction of the car is calculated using the roll, pitch and yaw
|
* @details The direction of the car is calculated using the roll, pitch and yaw
|
||||||
* The roll and pitch are calculated using the accelerometer data
|
* The roll and pitch are calculated using the accelerometer data
|
||||||
* The yaw is calculated using the magnetometer data
|
* The yaw is calculated using the magnetometer and accelerometer data
|
||||||
* The roll, pitch and yaw are combined to calculate the direction
|
* The roll, pitch and yaw are combined to calculate the direction
|
||||||
* of the car
|
* of the car with a complementary filter and compensating for the
|
||||||
*
|
* temperature.
|
||||||
* The direction of the car is calculated using the complementary
|
|
||||||
* filter
|
|
||||||
*
|
*
|
||||||
* The complementary filter is used to combine the accelerometer
|
* The complementary filter is used to combine the accelerometer
|
||||||
* and magnetometer data to calculate the direction of the car
|
* and magnetometer data (yaw) to calculate the direction of the car
|
||||||
*
|
*
|
||||||
* Source:
|
* Source:
|
||||||
* https://www.nxp.com/docs/en/application-note/AN3461.pdf
|
* https://www.nxp.com/docs/en/application-note/AN3461.pdf
|
||||||
|
|
|
@ -30,9 +30,9 @@ main (void)
|
||||||
{
|
{
|
||||||
stdio_usb_init();
|
stdio_usb_init();
|
||||||
|
|
||||||
sleep_ms(2000);
|
// sleep_ms(2000);
|
||||||
|
|
||||||
printf("Test started!\n");
|
// printf("Test started!\n");
|
||||||
magnetometer_init();
|
magnetometer_init();
|
||||||
|
|
||||||
launch();
|
launch();
|
||||||
|
|
|
@ -17,14 +17,57 @@
|
||||||
* @param right_speed The speed of the right motor, from 0.0 to 1.0
|
* @param right_speed The speed of the right motor, from 0.0 to 1.0
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
set_wheel_direction (uint32_t direction)
|
set_wheel_direction(uint32_t direction)
|
||||||
{
|
{
|
||||||
static const uint32_t mask = DIRECTION_LEFT_FORWARD |
|
static const uint32_t mask
|
||||||
DIRECTION_LEFT_BACKWARD |
|
= DIRECTION_LEFT_FORWARD | DIRECTION_LEFT_BACKWARD
|
||||||
DIRECTION_RIGHT_FORWARD |
|
| DIRECTION_RIGHT_FORWARD | DIRECTION_RIGHT_BACKWARD;
|
||||||
DIRECTION_RIGHT_BACKWARD;
|
|
||||||
|
|
||||||
gpio_put_masked(mask, 0U);
|
gpio_put_masked(mask, 0U);
|
||||||
gpio_set_mask(direction);
|
gpio_set_mask(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Turn the wheel, must set the priority higher than the motor PID task
|
||||||
|
* @param direction The direction of the wheel
|
||||||
|
* @param direction_after The direction of the wheel after turning
|
||||||
|
* @param speed_after The speed of the wheel after turning
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
turn_wheel(uint32_t direction)
|
||||||
|
{
|
||||||
|
set_wheel_speed(0u);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
float initial_right = g_motor_right.speed.distance_cm;
|
||||||
|
float initial_left = g_motor_left.speed.distance_cm;
|
||||||
|
|
||||||
|
set_wheel_direction(direction);
|
||||||
|
set_wheel_speed(3500u);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// gap between wheels = 11.3cm, to turn 90 degrees, need to travel
|
||||||
|
// 11.3 * pi / 4 = 8.9cm
|
||||||
|
if (g_motor_left.speed.distance_cm - initial_left >= 6.8f)
|
||||||
|
{
|
||||||
|
g_motor_left.pwm.level = 0;
|
||||||
|
pwm_set_chan_level(g_motor_left.pwm.slice_num,
|
||||||
|
g_motor_left.pwm.channel,
|
||||||
|
g_motor_left.pwm.level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_motor_right.speed.distance_cm - initial_right >= 6.8f)
|
||||||
|
{
|
||||||
|
g_motor_right.pwm.level = 0;
|
||||||
|
pwm_set_chan_level(g_motor_right.pwm.slice_num,
|
||||||
|
g_motor_right.pwm.channel,
|
||||||
|
g_motor_right.pwm.level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_motor_left.pwm.level == 0u && g_motor_right.pwm.level == 0u)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
|
@ -19,20 +19,23 @@
|
||||||
|
|
||||||
#include "motor_config.h"
|
#include "motor_config.h"
|
||||||
|
|
||||||
motor_speed_t g_motor_speed_left = { .pwm_level = 2500u,
|
motor_t g_motor_left = { .pwm.level = 0u,
|
||||||
.pwm_channel = PWM_CHAN_A,
|
.pwm.channel = PWM_CHAN_A,
|
||||||
.distance = 0.0f,};
|
.speed.distance_cm = 0.0f };
|
||||||
|
|
||||||
motor_speed_t g_motor_speed_right = { .pwm_level = 2500u,
|
motor_t g_motor_right = { .pwm.level = 0u,
|
||||||
.pwm_channel = PWM_CHAN_B,
|
.pwm.channel = PWM_CHAN_B,
|
||||||
.distance = 0.0f,};
|
.speed.distance_cm = 0.0f,
|
||||||
|
.pid.kp_value = 1000.f,
|
||||||
|
.pid.ki_value = 0.0f,
|
||||||
|
.pid.kd_value = 10000.0f,};
|
||||||
|
|
||||||
void
|
void
|
||||||
motor_init(void)
|
motor_init(void)
|
||||||
{
|
{
|
||||||
// Semaphore
|
// Semaphore
|
||||||
g_motor_speed_left.sem = xSemaphoreCreateBinary();
|
g_motor_left.sem = xSemaphoreCreateBinary();
|
||||||
g_motor_speed_right.sem = xSemaphoreCreateBinary();
|
g_motor_right.sem = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
gpio_init(SPEED_PIN_RIGHT);
|
gpio_init(SPEED_PIN_RIGHT);
|
||||||
gpio_init(SPEED_PIN_LEFT);
|
gpio_init(SPEED_PIN_LEFT);
|
||||||
|
@ -54,21 +57,21 @@ motor_init(void)
|
||||||
gpio_set_function(PWM_PIN_LEFT, GPIO_FUNC_PWM);
|
gpio_set_function(PWM_PIN_LEFT, GPIO_FUNC_PWM);
|
||||||
gpio_set_function(PWM_PIN_RIGHT, GPIO_FUNC_PWM);
|
gpio_set_function(PWM_PIN_RIGHT, GPIO_FUNC_PWM);
|
||||||
|
|
||||||
g_motor_speed_left.slice_num = pwm_gpio_to_slice_num(PWM_PIN_LEFT);
|
g_motor_left.pwm.slice_num = pwm_gpio_to_slice_num(PWM_PIN_LEFT);
|
||||||
g_motor_speed_right.slice_num = pwm_gpio_to_slice_num(PWM_PIN_RIGHT);
|
g_motor_right.pwm.slice_num = pwm_gpio_to_slice_num(PWM_PIN_RIGHT);
|
||||||
|
|
||||||
// NOTE: PWM clock is 125MHz for raspberrypi pico w by default
|
// NOTE: PWM clock is 125MHz for raspberrypi pico w by default
|
||||||
|
|
||||||
// 125MHz / 250 = 500kHz
|
// 125MHz / 250 = 500kHz
|
||||||
pwm_set_clkdiv(g_motor_speed_left.slice_num, PWM_CLK_DIV);
|
pwm_set_clkdiv(g_motor_left.pwm.slice_num, PWM_CLK_DIV);
|
||||||
pwm_set_clkdiv(g_motor_speed_right.slice_num, PWM_CLK_DIV);
|
pwm_set_clkdiv(g_motor_right.pwm.slice_num, PWM_CLK_DIV);
|
||||||
|
|
||||||
// have them to be 500kHz / 5000 = 100Hz
|
// have them to be 500kHz / 5000 = 100Hz
|
||||||
pwm_set_wrap(g_motor_speed_left.slice_num, (PWM_WRAP - 1U));
|
pwm_set_wrap(g_motor_left.pwm.slice_num, (PWM_WRAP - 1U));
|
||||||
pwm_set_wrap(g_motor_speed_right.slice_num, (PWM_WRAP - 1U));
|
pwm_set_wrap(g_motor_right.pwm.slice_num, (PWM_WRAP - 1U));
|
||||||
|
|
||||||
pwm_set_enabled(g_motor_speed_left.slice_num, true);
|
pwm_set_enabled(g_motor_left.pwm.slice_num, true);
|
||||||
pwm_set_enabled(g_motor_speed_right.slice_num, true);
|
pwm_set_enabled(g_motor_right.pwm.slice_num, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MOTOR_INIT_H */
|
#endif /* MOTOR_INIT_H */
|
|
@ -16,18 +16,18 @@
|
||||||
* @return The control signal
|
* @return The control signal
|
||||||
*/
|
*/
|
||||||
float
|
float
|
||||||
compute_pid(const volatile float *target_speed,
|
compute_pid(float *integral, float *prev_error)
|
||||||
const volatile float *current_speed,
|
|
||||||
float *integral,
|
|
||||||
float *prev_error)
|
|
||||||
{
|
{
|
||||||
float error = *target_speed - *current_speed;
|
float error
|
||||||
|
= g_motor_left.speed.distance_cm - g_motor_right.speed.distance_cm;
|
||||||
|
|
||||||
*integral += error;
|
*integral += error;
|
||||||
|
|
||||||
float derivative = error - *prev_error;
|
float derivative = error - *prev_error;
|
||||||
|
|
||||||
float control_signal
|
float control_signal = g_motor_right.pid.kp_value * error
|
||||||
= PID_KP * error + PID_KI * (*integral) + PID_KD * derivative;
|
+ g_motor_right.pid.ki_value * (*integral)
|
||||||
|
+ g_motor_right.pid.kd_value * derivative;
|
||||||
|
|
||||||
*prev_error = error;
|
*prev_error = error;
|
||||||
|
|
||||||
|
@ -35,37 +35,42 @@ compute_pid(const volatile float *target_speed,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
motor_pid_task(void *p_param)
|
motor_pid_task(__unused void *p_param)
|
||||||
{
|
{
|
||||||
motor_speed_t *p_motor_speed = p_param;
|
|
||||||
float integral = 0.0f;
|
float integral = 0.0f;
|
||||||
float prev_error = 0.0f;
|
float prev_error = 0.0f;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
float control_signal = compute_pid(&(p_motor_speed->target_speed_cms),
|
if (g_motor_left.pwm.level == 0u)
|
||||||
&(p_motor_speed->current_speed_cms),
|
|
||||||
&integral, &prev_error);
|
|
||||||
|
|
||||||
if (p_motor_speed->pwm_level + control_signal > MAX_SPEED)
|
|
||||||
{
|
{
|
||||||
p_motor_speed->pwm_level = MAX_SPEED;
|
g_motor_right.pwm.level = 0;
|
||||||
}
|
pwm_set_chan_level(g_motor_right.pwm.slice_num,
|
||||||
else if (p_motor_speed->pwm_level + control_signal < MIN_SPEED)
|
g_motor_right.pwm.channel,
|
||||||
{
|
g_motor_right.pwm.level);
|
||||||
p_motor_speed->pwm_level = MIN_SPEED;
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
}
|
continue;
|
||||||
else
|
|
||||||
{
|
|
||||||
p_motor_speed->pwm_level = p_motor_speed->pwm_level + control_signal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("control signal: %f\n", control_signal);
|
float control_signal = compute_pid(&integral, &prev_error);
|
||||||
// printf("new pwm: %hu\n\n", p_motor_speed->pwm_level);
|
|
||||||
|
|
||||||
pwm_set_chan_level(p_motor_speed->slice_num,
|
float temp = (float) g_motor_right.pwm.level + control_signal * 0.05f;
|
||||||
p_motor_speed->pwm_channel,
|
|
||||||
p_motor_speed->pwm_level);
|
if (temp > MAX_SPEED)
|
||||||
|
{
|
||||||
|
temp = MAX_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp < MIN_SPEED)
|
||||||
|
{
|
||||||
|
temp = MIN_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_motor_right.pwm.level = (uint16_t) temp;
|
||||||
|
|
||||||
|
pwm_set_chan_level(g_motor_right.pwm.slice_num,
|
||||||
|
g_motor_right.pwm.channel,
|
||||||
|
g_motor_right.pwm.level);
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(50));
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ h_wheel_sensor_isr_handler(void)
|
||||||
gpio_acknowledge_irq(SPEED_PIN_LEFT, GPIO_IRQ_EDGE_FALL);
|
gpio_acknowledge_irq(SPEED_PIN_LEFT, GPIO_IRQ_EDGE_FALL);
|
||||||
|
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
xSemaphoreGiveFromISR(g_motor_speed_left.sem,
|
xSemaphoreGiveFromISR(g_motor_left.sem,
|
||||||
&xHigherPriorityTaskWoken);
|
&xHigherPriorityTaskWoken);
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ h_wheel_sensor_isr_handler(void)
|
||||||
gpio_acknowledge_irq(SPEED_PIN_RIGHT, GPIO_IRQ_EDGE_FALL);
|
gpio_acknowledge_irq(SPEED_PIN_RIGHT, GPIO_IRQ_EDGE_FALL);
|
||||||
|
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
xSemaphoreGiveFromISR(g_motor_speed_right.sem,
|
xSemaphoreGiveFromISR(g_motor_right.sem,
|
||||||
&xHigherPriorityTaskWoken);
|
&xHigherPriorityTaskWoken);
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ h_wheel_sensor_isr_handler(void)
|
||||||
void
|
void
|
||||||
monitor_wheel_speed_task(void *pvParameters)
|
monitor_wheel_speed_task(void *pvParameters)
|
||||||
{
|
{
|
||||||
volatile motor_speed_t *p_motor_speed = NULL;
|
volatile motor_t *p_motor = NULL;
|
||||||
p_motor_speed = (motor_speed_t *)pvParameters;
|
p_motor = (motor_t *)pvParameters;
|
||||||
|
|
||||||
uint64_t curr_time = 0u;
|
uint64_t curr_time = 0u;
|
||||||
uint64_t prev_time = 0u;
|
uint64_t prev_time = 0u;
|
||||||
|
@ -51,7 +51,7 @@ monitor_wheel_speed_task(void *pvParameters)
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (xSemaphoreTake(p_motor_speed->sem, pdMS_TO_TICKS(100))
|
if (xSemaphoreTake(p_motor->sem, pdMS_TO_TICKS(100))
|
||||||
== pdTRUE)
|
== pdTRUE)
|
||||||
{
|
{
|
||||||
curr_time = time_us_64();
|
curr_time = time_us_64();
|
||||||
|
@ -62,20 +62,56 @@ monitor_wheel_speed_task(void *pvParameters)
|
||||||
// distance = circumference / 20
|
// distance = circumference / 20
|
||||||
// circumference = 2 * pi * 3.25 cm = 20.4203522483 cm
|
// circumference = 2 * pi * 3.25 cm = 20.4203522483 cm
|
||||||
// distance = 20.4203522483 cm / 20 = 1.02101761242 cm
|
// distance = 20.4203522483 cm / 20 = 1.02101761242 cm
|
||||||
p_motor_speed->current_speed_cms = (float) (1.02101761242f /
|
p_motor->speed.current_cms
|
||||||
(elapsed_time /
|
= (float) (1021017.61242f / elapsed_time);
|
||||||
1000000.f));
|
|
||||||
|
|
||||||
p_motor_speed->distance += 1.02101761242f;
|
p_motor->speed.distance_cm += 1.02101761242f;
|
||||||
|
|
||||||
// printf("speed: %f cm/s\n", p_motor_speed->current_speed_cms);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p_motor_speed->current_speed_cms = 0.f;
|
p_motor->speed.current_cms = 0.f;
|
||||||
// printf("stopped\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("distance: %f cm\n", p_motor_speed->distance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set the distance to travel before stopping, must be called after
|
||||||
|
* setting the speed and direction.
|
||||||
|
* @param distance_cm distance to travel in cm
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
distance_to_stop(float distance_cm)
|
||||||
|
{
|
||||||
|
float initial = g_motor_right.speed.distance_cm;
|
||||||
|
printf("initial: %f\n", initial);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (g_motor_right.speed.distance_cm - initial >= distance_cm)
|
||||||
|
{
|
||||||
|
g_motor_right.pwm.level = 0;
|
||||||
|
g_motor_left.pwm.level = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set the speed of the wheels
|
||||||
|
* @param pwm_level The pwm_level of the wheels, from 0 to 5000
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
set_wheel_speed(uint32_t pwm_level)
|
||||||
|
{
|
||||||
|
g_motor_right.pwm.level = pwm_level;
|
||||||
|
g_motor_left.pwm.level = pwm_level;
|
||||||
|
|
||||||
|
pwm_set_chan_level(g_motor_right.pwm.slice_num,
|
||||||
|
g_motor_right.pwm.channel,
|
||||||
|
g_motor_right.pwm.level);
|
||||||
|
pwm_set_chan_level(g_motor_left.pwm.slice_num,
|
||||||
|
g_motor_left.pwm.channel,
|
||||||
|
g_motor_left.pwm.level);
|
||||||
|
}
|
|
@ -4,25 +4,35 @@
|
||||||
#include "motor_direction.h"
|
#include "motor_direction.h"
|
||||||
#include "motor_pid.h"
|
#include "motor_pid.h"
|
||||||
|
|
||||||
#define WHEEL_SPEED_PRIO (tskIDLE_PRIORITY + 1UL)
|
#define WHEEL_SPEED_PRIO (tskIDLE_PRIORITY + 2UL)
|
||||||
|
#define WHEEL_CONTROL_PRIO (tskIDLE_PRIORITY + 2UL)
|
||||||
|
#define WHEEL_PID_PRIO (tskIDLE_PRIORITY + 2UL)
|
||||||
|
|
||||||
void
|
static void
|
||||||
test_speed_change_task(void *p_param)
|
motor_control_task(__unused void *p_param)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
g_motor_speed_left.target_speed_cms = 15.0f;
|
set_wheel_direction(DIRECTION_FORWARD);
|
||||||
g_motor_speed_right.target_speed_cms = 15.0f;
|
set_wheel_speed(3000u);
|
||||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
distance_to_stop(30);
|
||||||
|
|
||||||
// g_motor_speed_left.target_speed_cms = 20.0f;
|
set_wheel_direction(DIRECTION_BACKWARD);
|
||||||
// g_motor_speed_right.target_speed_cms = 20.0f;
|
set_wheel_speed(3000u);
|
||||||
// vTaskDelay(pdMS_TO_TICKS(5000));
|
distance_to_stop(30);
|
||||||
|
|
||||||
g_motor_speed_left.target_speed_cms = 0.0f;
|
turn_wheel(DIRECTION_LEFT);
|
||||||
g_motor_speed_right.target_speed_cms = 0.0f;
|
set_wheel_direction(DIRECTION_FORWARD);
|
||||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
set_wheel_speed(3000u);
|
||||||
|
distance_to_stop(30);
|
||||||
|
|
||||||
|
turn_wheel(DIRECTION_RIGHT);
|
||||||
|
set_wheel_direction(DIRECTION_FORWARD);
|
||||||
|
set_wheel_speed(3000u);
|
||||||
|
distance_to_stop(30);
|
||||||
|
|
||||||
|
set_wheel_speed(0u);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,23 +49,18 @@ launch()
|
||||||
|
|
||||||
irq_set_enabled(IO_IRQ_BANK0, true);
|
irq_set_enabled(IO_IRQ_BANK0, true);
|
||||||
|
|
||||||
|
// set_wheel_direction(DIRECTION_FORWARD);
|
||||||
|
// set_wheel_speed(3000);
|
||||||
|
|
||||||
// Left wheel
|
// Left wheel
|
||||||
//
|
//
|
||||||
// TaskHandle_t h_monitor_left_wheel_speed_task_handle = NULL;
|
TaskHandle_t h_monitor_left_wheel_speed_task_handle = NULL;
|
||||||
// xTaskCreate(monitor_wheel_speed_task,
|
xTaskCreate(monitor_wheel_speed_task,
|
||||||
// "monitor_left_wheel_speed_task",
|
"monitor_left_wheel_speed_task",
|
||||||
// configMINIMAL_STACK_SIZE,
|
configMINIMAL_STACK_SIZE,
|
||||||
// (void *)&g_motor_speed_left,
|
(void *)&g_motor_left,
|
||||||
// WHEEL_SPEED_PRIO,
|
WHEEL_SPEED_PRIO,
|
||||||
// &h_monitor_left_wheel_speed_task_handle);
|
&h_monitor_left_wheel_speed_task_handle);
|
||||||
|
|
||||||
// TaskHandle_t h_motor_pid_left_task_handle = NULL;
|
|
||||||
// xTaskCreate(motor_pid_task,
|
|
||||||
// "motor_pid_task",
|
|
||||||
// configMINIMAL_STACK_SIZE,
|
|
||||||
// (void *)&g_motor_speed_left,
|
|
||||||
// WHEEL_SPEED_PRIO,
|
|
||||||
// &h_motor_pid_left_task_handle);
|
|
||||||
|
|
||||||
// Right wheel
|
// Right wheel
|
||||||
//
|
//
|
||||||
|
@ -63,7 +68,7 @@ launch()
|
||||||
xTaskCreate(monitor_wheel_speed_task,
|
xTaskCreate(monitor_wheel_speed_task,
|
||||||
"monitor_wheel_speed_task",
|
"monitor_wheel_speed_task",
|
||||||
configMINIMAL_STACK_SIZE,
|
configMINIMAL_STACK_SIZE,
|
||||||
(void *)&g_motor_speed_right,
|
(void *)&g_motor_right,
|
||||||
WHEEL_SPEED_PRIO,
|
WHEEL_SPEED_PRIO,
|
||||||
&h_monitor_right_wheel_speed_task_handle);
|
&h_monitor_right_wheel_speed_task_handle);
|
||||||
|
|
||||||
|
@ -71,19 +76,18 @@ launch()
|
||||||
xTaskCreate(motor_pid_task,
|
xTaskCreate(motor_pid_task,
|
||||||
"motor_pid_task",
|
"motor_pid_task",
|
||||||
configMINIMAL_STACK_SIZE,
|
configMINIMAL_STACK_SIZE,
|
||||||
(void *)&g_motor_speed_right,
|
(void *)&g_motor_right,
|
||||||
WHEEL_SPEED_PRIO,
|
WHEEL_PID_PRIO,
|
||||||
&h_motor_pid_right_task_handle);
|
&h_motor_pid_right_task_handle);
|
||||||
|
|
||||||
// Test speed change
|
// control task
|
||||||
//
|
TaskHandle_t h_motor_turning_task_handle = NULL;
|
||||||
TaskHandle_t h_test_speed_change_task_handle = NULL;
|
xTaskCreate(motor_control_task,
|
||||||
xTaskCreate(test_speed_change_task,
|
"motor_turning_task",
|
||||||
"test_speed_change_task",
|
|
||||||
configMINIMAL_STACK_SIZE,
|
configMINIMAL_STACK_SIZE,
|
||||||
NULL,
|
NULL,
|
||||||
WHEEL_SPEED_PRIO,
|
WHEEL_CONTROL_PRIO,
|
||||||
&h_test_speed_change_task_handle);
|
&h_motor_turning_task_handle);
|
||||||
|
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
}
|
}
|
||||||
|
@ -93,11 +97,10 @@ main(void)
|
||||||
{
|
{
|
||||||
stdio_usb_init();
|
stdio_usb_init();
|
||||||
|
|
||||||
sleep_ms(2000);
|
sleep_ms(4000);
|
||||||
printf("Test started!\n");
|
printf("Test started!\n");
|
||||||
|
|
||||||
motor_init();
|
motor_init();
|
||||||
set_wheel_direction(DIRECTION_LEFT_FORWARD | DIRECTION_RIGHT_FORWARD);
|
|
||||||
|
|
||||||
launch();
|
launch();
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ main (void)
|
||||||
|
|
||||||
line_sensor_setup();
|
line_sensor_setup();
|
||||||
|
|
||||||
|
init_ultrasonic();
|
||||||
|
|
||||||
initialize_car_state(); // TODO: Could be common functionality, To confirm
|
initialize_car_state(); // TODO: Could be common functionality, To confirm
|
||||||
// during Integration
|
// during Integration
|
||||||
launch();
|
launch();
|
||||||
|
|
|
@ -3,89 +3,15 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define TRIG_PIN 0
|
#include "ultrasonic_sensor.h"
|
||||||
#define ECHO_PIN 1
|
|
||||||
|
|
||||||
int16_t counter = 0;
|
|
||||||
|
|
||||||
void
|
|
||||||
init_ultrasonic(void)
|
|
||||||
{
|
|
||||||
// Set up the echo pin
|
|
||||||
gpio_init(ECHO_PIN);
|
|
||||||
gpio_set_dir(ECHO_PIN, GPIO_IN);
|
|
||||||
|
|
||||||
// Set up the trigger pin
|
|
||||||
gpio_init(TRIG_PIN);
|
|
||||||
gpio_set_dir(TRIG_PIN, GPIO_OUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
KalmanFilter(float U)
|
|
||||||
{
|
|
||||||
static float R = 10; // noise convariance can be 10, higher better smooth
|
|
||||||
static float H = 1; // Measurement Map scalar
|
|
||||||
static float Q = 10; // initial estimated convariance
|
|
||||||
static float P = 0; // initial error covariance
|
|
||||||
static float U_hat = 0; // initial estimated state
|
|
||||||
static float K = 0; // initial Kalman gain
|
|
||||||
|
|
||||||
// Predict
|
|
||||||
//
|
|
||||||
K = P * H / (H * P * H + R); // Update Kalman gain
|
|
||||||
U_hat = U_hat + K * (U - H * U_hat); // Update estimated state
|
|
||||||
|
|
||||||
// Update error covariance
|
|
||||||
//
|
|
||||||
P = (1 - K * H) * P + Q;
|
|
||||||
|
|
||||||
return U_hat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
distance_task(__unused void *params)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
vTaskDelay(1000);
|
|
||||||
|
|
||||||
// Trigger the ultrasonic sensor
|
|
||||||
gpio_put(TRIG_PIN, 1);
|
|
||||||
sleep_us(10); // Keep the trigger on for 10 microseconds
|
|
||||||
gpio_put(TRIG_PIN, 0);
|
|
||||||
|
|
||||||
// Wait for the echo pulse to start
|
|
||||||
while (gpio_get(ECHO_PIN) == 0)
|
|
||||||
tight_loop_contents();
|
|
||||||
|
|
||||||
// Measure the pulse width (time taken for the echo to return)
|
|
||||||
uint32_t start_time = time_us_32();
|
|
||||||
while (gpio_get(ECHO_PIN) == 1)
|
|
||||||
tight_loop_contents();
|
|
||||||
uint32_t end_time = time_us_32();
|
|
||||||
|
|
||||||
// Calculate the distance (in centimeters)
|
|
||||||
uint32_t pulse_duration = end_time - start_time;
|
|
||||||
float distance = pulse_duration * 0.017; // Speed of sound at ~343 m/s
|
|
||||||
|
|
||||||
// printf("Distance: %.2f cm\n", distance);
|
|
||||||
// printf("Kalman Filtered Distance: %.2f cm\n", KalmanFilter(distance));
|
|
||||||
printf("%d,%.2f,%.2f\n", counter++, distance, KalmanFilter(distance));
|
|
||||||
|
|
||||||
// If gonna bang wall
|
|
||||||
//
|
|
||||||
if (distance < 5)
|
|
||||||
{
|
|
||||||
printf("Collision Imminent!\n");
|
|
||||||
// Proc stop
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vLaunch(void)
|
vLaunch(void)
|
||||||
{
|
{
|
||||||
|
gpio_set_irq_enabled_with_callback(ECHO_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, echo_handler);
|
||||||
|
|
||||||
|
irq_set_enabled(IO_IRQ_BANK0, true);
|
||||||
|
|
||||||
TaskHandle_t disttask;
|
TaskHandle_t disttask;
|
||||||
xTaskCreate(distance_task,
|
xTaskCreate(distance_task,
|
||||||
"TestDistThread",
|
"TestDistThread",
|
||||||
|
@ -94,8 +20,6 @@ vLaunch(void)
|
||||||
1,
|
1,
|
||||||
&disttask);
|
&disttask);
|
||||||
|
|
||||||
// Start the tasks and timer running.
|
|
||||||
//
|
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +28,7 @@ main(void)
|
||||||
{
|
{
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
init_ultrasonic();
|
init_ultrasonic();
|
||||||
sleep_ms(3000);
|
sleep_ms(1000);
|
||||||
vLaunch();
|
vLaunch();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -9,40 +9,73 @@
|
||||||
|
|
||||||
#include "ultrasonic_init.h"
|
#include "ultrasonic_init.h"
|
||||||
|
|
||||||
void distance_task(__unused void *params)
|
volatile uint32_t start_time;
|
||||||
|
volatile uint32_t end_time;
|
||||||
|
volatile bool echo_rising = false;
|
||||||
|
|
||||||
|
float
|
||||||
|
KalmanFilter(float U)
|
||||||
|
{
|
||||||
|
static float R = 10; // noise convariance can be 10, higher better smooth
|
||||||
|
static float H = 1; // Measurement Map scalar
|
||||||
|
static float Q = 10; // initial estimated convariance
|
||||||
|
static float P = 0; // initial error covariance
|
||||||
|
static float U_hat = 0; // initial estimated state
|
||||||
|
static float K = 0; // initial Kalman gain
|
||||||
|
|
||||||
|
// Predict
|
||||||
|
//
|
||||||
|
K = P * H / (H * P * H + R); // Update Kalman gain
|
||||||
|
U_hat = U_hat + K * (U - H * U_hat); // Update estimated state
|
||||||
|
|
||||||
|
// Update error covariance
|
||||||
|
//
|
||||||
|
P = (1 - K * H) * P + Q;
|
||||||
|
|
||||||
|
return U_hat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
echo_handler()
|
||||||
|
{
|
||||||
|
if (gpio_get(ECHO_PIN))
|
||||||
|
{
|
||||||
|
start_time = time_us_32();
|
||||||
|
echo_rising = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end_time = time_us_32();
|
||||||
|
echo_rising = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
distance_task(__unused void *params)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
vTaskDelay(500);
|
vTaskDelay(1000);
|
||||||
|
|
||||||
// Trigger the ultrasonic sensor
|
|
||||||
gpio_put(TRIG_PIN, 1);
|
gpio_put(TRIG_PIN, 1);
|
||||||
sleep_us(10); // Keep the trigger on for 10 microseconds
|
sleep_us(10);
|
||||||
gpio_put(TRIG_PIN, 0);
|
gpio_put(TRIG_PIN, 0);
|
||||||
|
|
||||||
// Wait for the echo pulse to start
|
while (echo_rising)
|
||||||
while (gpio_get(ECHO_PIN) == 0)
|
{
|
||||||
tight_loop_contents();
|
tight_loop_contents();
|
||||||
|
}
|
||||||
// Measure the pulse width (time taken for the echo to return)
|
|
||||||
uint32_t start_time = time_us_32();
|
|
||||||
while (gpio_get(ECHO_PIN) == 1)
|
|
||||||
tight_loop_contents();
|
|
||||||
uint32_t end_time = time_us_32();
|
|
||||||
|
|
||||||
// Calculate the distance (in centimeters)
|
// Calculate the distance (in centimeters)
|
||||||
uint32_t pulse_duration = end_time - start_time;
|
uint32_t pulse_duration = end_time - start_time;
|
||||||
float distance = pulse_duration * 0.017; // Speed of sound at ~343 m/s
|
float distance = (pulse_duration * 0.034 / 2) * 1.125; // Speed of sound in cm/us
|
||||||
|
|
||||||
printf("Distance: %.2f cm\n", distance);
|
// printf("Distance: %.2f cm\n", distance);
|
||||||
|
printf("Kalman Filtered Distance: %.2f cm\n", KalmanFilter(distance));
|
||||||
|
|
||||||
// If gonna bang wall
|
|
||||||
//
|
|
||||||
if (distance < 5)
|
if (distance < 5)
|
||||||
{
|
{
|
||||||
printf("Collision Imminent!\n");
|
printf("Collision Imminent!\n");
|
||||||
// Proc stop
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue