barcode
This commit is contained in:
commit
2a38789890
|
@ -5,6 +5,7 @@ add_subdirectory(line_sensor)
|
|||
add_subdirectory(car)
|
||||
add_subdirectory(ultrasonic_sensor)
|
||||
add_subdirectory(magnetometer)
|
||||
add_subdirectory(frontend)
|
||||
|
||||
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}/line_sensor
|
||||
${CMAKE_CURRENT_LIST_DIR}/ultrasonic_sensor
|
||||
${CMAKE_CURRENT_LIST_DIR}/frontend
|
||||
)
|
||||
target_link_libraries(rtos_car
|
||||
pico_cyw43_arch_lwip_sys_freertos
|
||||
|
|
|
@ -10,6 +10,18 @@
|
|||
#define ALPHA ( 0.01f ) // Complementary
|
||||
// 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
|
||||
*/
|
||||
|
|
|
@ -18,42 +18,67 @@
|
|||
#define DIRECTION_LEFT_FORWARD (1U << DIRECTION_PIN_LEFT_IN4)
|
||||
#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_LEFT 16U
|
||||
|
||||
#define PWM_CLK_DIV 250.f
|
||||
#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 MIN_SPEED 0U // To be changed
|
||||
|
||||
/*!
|
||||
* @brief Structure for the motor speed
|
||||
* @param target_speed The target speed of the wheel, in cm/s
|
||||
* @param pwm_level The pwm level of the wheel, from 0 to 5000
|
||||
* @param sem The semaphore for the wheel
|
||||
* @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
|
||||
* @brief Structure for the motor speed parameters
|
||||
* @param target_speed_cms Target speed in cm/s
|
||||
* @param current_speed_cms Current speed in cm/s
|
||||
* @param distance_cm Distance travelled in cm
|
||||
*/
|
||||
typedef struct {
|
||||
float target_speed_cms;
|
||||
float current_speed_cms;
|
||||
uint16_t pwm_level;
|
||||
SemaphoreHandle_t sem;
|
||||
uint slice_num;
|
||||
uint pwm_channel;
|
||||
float distance;
|
||||
float current_cms;
|
||||
float distance_cm;
|
||||
} 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 */
|
|
@ -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,14 +15,35 @@
|
|||
*
|
||||
* @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
|
||||
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);
|
||||
|
@ -31,9 +52,6 @@ monitor_left_sensor_task(__unused void *params) {
|
|||
&state,
|
||||
sizeof(state_t),
|
||||
0);
|
||||
// Reset the flag
|
||||
left_sensor_triggered = pdFALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,12 +64,32 @@ monitor_left_sensor_task(__unused void *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
|
||||
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);
|
||||
|
@ -60,9 +98,6 @@ monitor_right_sensor_task(void *params) {
|
|||
&state,
|
||||
sizeof(state_t),
|
||||
0);
|
||||
// Reset the flag
|
||||
right_sensor_triggered = pdFALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,17 +24,17 @@ launch()
|
|||
|
||||
irq_set_enabled(IO_IRQ_BANK0, true);
|
||||
|
||||
// struct repeating_timer g_left_sensor_timer;
|
||||
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||
// h_left_sensor_timer_handler,
|
||||
// NULL,
|
||||
// &g_left_sensor_timer);
|
||||
//
|
||||
// struct repeating_timer g_right_sensor_timer;
|
||||
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||
// h_right_sensor_timer_handler,
|
||||
// NULL,
|
||||
// &g_right_sensor_timer);
|
||||
struct repeating_timer g_left_sensor_timer;
|
||||
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||
h_left_sensor_timer_handler,
|
||||
NULL,
|
||||
&g_left_sensor_timer);
|
||||
|
||||
struct repeating_timer g_right_sensor_timer;
|
||||
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
|
||||
h_right_sensor_timer_handler,
|
||||
NULL,
|
||||
&g_right_sensor_timer);
|
||||
|
||||
TaskHandle_t h_monitor_left_sensor_task;
|
||||
xTaskCreate(monitor_left_sensor_task,
|
||||
|
|
|
@ -28,15 +28,7 @@
|
|||
#define LSM303_TEMP_OUT_H_M 0x31
|
||||
#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 MAG_ADDR 0x1E
|
||||
|
|
|
@ -6,15 +6,13 @@
|
|||
*
|
||||
* @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 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
|
||||
* of the car
|
||||
*
|
||||
* The direction of the car is calculated using the complementary
|
||||
* filter
|
||||
* of the car with a complementary filter and compensating for the
|
||||
* temperature.
|
||||
*
|
||||
* 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:
|
||||
* https://www.nxp.com/docs/en/application-note/AN3461.pdf
|
||||
|
|
|
@ -30,9 +30,9 @@ main (void)
|
|||
{
|
||||
stdio_usb_init();
|
||||
|
||||
sleep_ms(2000);
|
||||
// sleep_ms(2000);
|
||||
|
||||
printf("Test started!\n");
|
||||
// printf("Test started!\n");
|
||||
magnetometer_init();
|
||||
|
||||
launch();
|
||||
|
|
|
@ -17,14 +17,57 @@
|
|||
* @param right_speed The speed of the right motor, from 0.0 to 1.0
|
||||
*/
|
||||
void
|
||||
set_wheel_direction (uint32_t direction)
|
||||
set_wheel_direction(uint32_t direction)
|
||||
{
|
||||
static const uint32_t mask = DIRECTION_LEFT_FORWARD |
|
||||
DIRECTION_LEFT_BACKWARD |
|
||||
DIRECTION_RIGHT_FORWARD |
|
||||
DIRECTION_RIGHT_BACKWARD;
|
||||
static const uint32_t mask
|
||||
= DIRECTION_LEFT_FORWARD | DIRECTION_LEFT_BACKWARD
|
||||
| DIRECTION_RIGHT_FORWARD | DIRECTION_RIGHT_BACKWARD;
|
||||
|
||||
gpio_put_masked(mask, 0U);
|
||||
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"
|
||||
|
||||
motor_speed_t g_motor_speed_left = { .pwm_level = 2500u,
|
||||
.pwm_channel = PWM_CHAN_A,
|
||||
.distance = 0.0f,};
|
||||
motor_t g_motor_left = { .pwm.level = 0u,
|
||||
.pwm.channel = PWM_CHAN_A,
|
||||
.speed.distance_cm = 0.0f };
|
||||
|
||||
motor_speed_t g_motor_speed_right = { .pwm_level = 2500u,
|
||||
.pwm_channel = PWM_CHAN_B,
|
||||
.distance = 0.0f,};
|
||||
motor_t g_motor_right = { .pwm.level = 0u,
|
||||
.pwm.channel = PWM_CHAN_B,
|
||||
.speed.distance_cm = 0.0f,
|
||||
.pid.kp_value = 1000.f,
|
||||
.pid.ki_value = 0.0f,
|
||||
.pid.kd_value = 10000.0f,};
|
||||
|
||||
void
|
||||
motor_init(void)
|
||||
{
|
||||
// Semaphore
|
||||
g_motor_speed_left.sem = xSemaphoreCreateBinary();
|
||||
g_motor_speed_right.sem = xSemaphoreCreateBinary();
|
||||
g_motor_left.sem = xSemaphoreCreateBinary();
|
||||
g_motor_right.sem = xSemaphoreCreateBinary();
|
||||
|
||||
gpio_init(SPEED_PIN_RIGHT);
|
||||
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_RIGHT, GPIO_FUNC_PWM);
|
||||
|
||||
g_motor_speed_left.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_left.pwm.slice_num = pwm_gpio_to_slice_num(PWM_PIN_LEFT);
|
||||
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
|
||||
|
||||
// 125MHz / 250 = 500kHz
|
||||
pwm_set_clkdiv(g_motor_speed_left.slice_num, PWM_CLK_DIV);
|
||||
pwm_set_clkdiv(g_motor_speed_right.slice_num, PWM_CLK_DIV);
|
||||
pwm_set_clkdiv(g_motor_left.pwm.slice_num, PWM_CLK_DIV);
|
||||
pwm_set_clkdiv(g_motor_right.pwm.slice_num, PWM_CLK_DIV);
|
||||
|
||||
// have them to be 500kHz / 5000 = 100Hz
|
||||
pwm_set_wrap(g_motor_speed_left.slice_num, (PWM_WRAP - 1U));
|
||||
pwm_set_wrap(g_motor_speed_right.slice_num, (PWM_WRAP - 1U));
|
||||
pwm_set_wrap(g_motor_left.pwm.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_speed_right.slice_num, true);
|
||||
pwm_set_enabled(g_motor_left.pwm.slice_num, true);
|
||||
pwm_set_enabled(g_motor_right.pwm.slice_num, true);
|
||||
}
|
||||
|
||||
#endif /* MOTOR_INIT_H */
|
|
@ -16,18 +16,18 @@
|
|||
* @return The control signal
|
||||
*/
|
||||
float
|
||||
compute_pid(const volatile float *target_speed,
|
||||
const volatile float *current_speed,
|
||||
float *integral,
|
||||
float *prev_error)
|
||||
compute_pid(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;
|
||||
|
||||
float derivative = error - *prev_error;
|
||||
|
||||
float control_signal
|
||||
= PID_KP * error + PID_KI * (*integral) + PID_KD * derivative;
|
||||
float control_signal = g_motor_right.pid.kp_value * error
|
||||
+ g_motor_right.pid.ki_value * (*integral)
|
||||
+ g_motor_right.pid.kd_value * derivative;
|
||||
|
||||
*prev_error = error;
|
||||
|
||||
|
@ -35,37 +35,42 @@ compute_pid(const volatile float *target_speed,
|
|||
}
|
||||
|
||||
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 prev_error = 0.0f;
|
||||
float integral = 0.0f;
|
||||
float prev_error = 0.0f;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
float control_signal = compute_pid(&(p_motor_speed->target_speed_cms),
|
||||
&(p_motor_speed->current_speed_cms),
|
||||
&integral, &prev_error);
|
||||
|
||||
if (p_motor_speed->pwm_level + control_signal > MAX_SPEED)
|
||||
if (g_motor_left.pwm.level == 0u)
|
||||
{
|
||||
p_motor_speed->pwm_level = MAX_SPEED;
|
||||
}
|
||||
else if (p_motor_speed->pwm_level + control_signal < MIN_SPEED)
|
||||
{
|
||||
p_motor_speed->pwm_level = MIN_SPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_motor_speed->pwm_level = p_motor_speed->pwm_level + control_signal;
|
||||
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);
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
continue;
|
||||
}
|
||||
|
||||
// printf("control signal: %f\n", control_signal);
|
||||
// printf("new pwm: %hu\n\n", p_motor_speed->pwm_level);
|
||||
float control_signal = compute_pid(&integral, &prev_error);
|
||||
|
||||
pwm_set_chan_level(p_motor_speed->slice_num,
|
||||
p_motor_speed->pwm_channel,
|
||||
p_motor_speed->pwm_level);
|
||||
float temp = (float) g_motor_right.pwm.level + control_signal * 0.05f;
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ h_wheel_sensor_isr_handler(void)
|
|||
gpio_acknowledge_irq(SPEED_PIN_LEFT, GPIO_IRQ_EDGE_FALL);
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(g_motor_speed_left.sem,
|
||||
xSemaphoreGiveFromISR(g_motor_left.sem,
|
||||
&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);
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(g_motor_speed_right.sem,
|
||||
xSemaphoreGiveFromISR(g_motor_right.sem,
|
||||
&xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ h_wheel_sensor_isr_handler(void)
|
|||
void
|
||||
monitor_wheel_speed_task(void *pvParameters)
|
||||
{
|
||||
volatile motor_speed_t *p_motor_speed = NULL;
|
||||
p_motor_speed = (motor_speed_t *)pvParameters;
|
||||
volatile motor_t *p_motor = NULL;
|
||||
p_motor = (motor_t *)pvParameters;
|
||||
|
||||
uint64_t curr_time = 0u;
|
||||
uint64_t prev_time = 0u;
|
||||
|
@ -51,7 +51,7 @@ monitor_wheel_speed_task(void *pvParameters)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (xSemaphoreTake(p_motor_speed->sem, pdMS_TO_TICKS(100))
|
||||
if (xSemaphoreTake(p_motor->sem, pdMS_TO_TICKS(100))
|
||||
== pdTRUE)
|
||||
{
|
||||
curr_time = time_us_64();
|
||||
|
@ -62,20 +62,56 @@ monitor_wheel_speed_task(void *pvParameters)
|
|||
// distance = circumference / 20
|
||||
// circumference = 2 * pi * 3.25 cm = 20.4203522483 cm
|
||||
// distance = 20.4203522483 cm / 20 = 1.02101761242 cm
|
||||
p_motor_speed->current_speed_cms = (float) (1.02101761242f /
|
||||
(elapsed_time /
|
||||
1000000.f));
|
||||
p_motor->speed.current_cms
|
||||
= (float) (1021017.61242f / elapsed_time);
|
||||
|
||||
p_motor_speed->distance += 1.02101761242f;
|
||||
|
||||
// printf("speed: %f cm/s\n", p_motor_speed->current_speed_cms);
|
||||
p_motor->speed.distance_cm += 1.02101761242f;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_motor_speed->current_speed_cms = 0.f;
|
||||
// printf("stopped\n");
|
||||
p_motor->speed.current_cms = 0.f;
|
||||
}
|
||||
|
||||
// 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_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
|
||||
test_speed_change_task(void *p_param)
|
||||
static void
|
||||
motor_control_task(__unused void *p_param)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
g_motor_speed_left.target_speed_cms = 15.0f;
|
||||
g_motor_speed_right.target_speed_cms = 15.0f;
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
set_wheel_direction(DIRECTION_FORWARD);
|
||||
set_wheel_speed(3000u);
|
||||
distance_to_stop(30);
|
||||
|
||||
// g_motor_speed_left.target_speed_cms = 20.0f;
|
||||
// g_motor_speed_right.target_speed_cms = 20.0f;
|
||||
// vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
set_wheel_direction(DIRECTION_BACKWARD);
|
||||
set_wheel_speed(3000u);
|
||||
distance_to_stop(30);
|
||||
|
||||
g_motor_speed_left.target_speed_cms = 0.0f;
|
||||
g_motor_speed_right.target_speed_cms = 0.0f;
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
turn_wheel(DIRECTION_LEFT);
|
||||
set_wheel_direction(DIRECTION_FORWARD);
|
||||
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);
|
||||
|
||||
// set_wheel_direction(DIRECTION_FORWARD);
|
||||
// set_wheel_speed(3000);
|
||||
|
||||
// Left wheel
|
||||
//
|
||||
// TaskHandle_t h_monitor_left_wheel_speed_task_handle = NULL;
|
||||
// xTaskCreate(monitor_wheel_speed_task,
|
||||
// "monitor_left_wheel_speed_task",
|
||||
// configMINIMAL_STACK_SIZE,
|
||||
// (void *)&g_motor_speed_left,
|
||||
// WHEEL_SPEED_PRIO,
|
||||
// &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);
|
||||
TaskHandle_t h_monitor_left_wheel_speed_task_handle = NULL;
|
||||
xTaskCreate(monitor_wheel_speed_task,
|
||||
"monitor_left_wheel_speed_task",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
(void *)&g_motor_left,
|
||||
WHEEL_SPEED_PRIO,
|
||||
&h_monitor_left_wheel_speed_task_handle);
|
||||
|
||||
// Right wheel
|
||||
//
|
||||
|
@ -63,7 +68,7 @@ launch()
|
|||
xTaskCreate(monitor_wheel_speed_task,
|
||||
"monitor_wheel_speed_task",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
(void *)&g_motor_speed_right,
|
||||
(void *)&g_motor_right,
|
||||
WHEEL_SPEED_PRIO,
|
||||
&h_monitor_right_wheel_speed_task_handle);
|
||||
|
||||
|
@ -71,19 +76,18 @@ launch()
|
|||
xTaskCreate(motor_pid_task,
|
||||
"motor_pid_task",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
(void *)&g_motor_speed_right,
|
||||
WHEEL_SPEED_PRIO,
|
||||
(void *)&g_motor_right,
|
||||
WHEEL_PID_PRIO,
|
||||
&h_motor_pid_right_task_handle);
|
||||
|
||||
// Test speed change
|
||||
//
|
||||
TaskHandle_t h_test_speed_change_task_handle = NULL;
|
||||
xTaskCreate(test_speed_change_task,
|
||||
"test_speed_change_task",
|
||||
// control task
|
||||
TaskHandle_t h_motor_turning_task_handle = NULL;
|
||||
xTaskCreate(motor_control_task,
|
||||
"motor_turning_task",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
WHEEL_SPEED_PRIO,
|
||||
&h_test_speed_change_task_handle);
|
||||
WHEEL_CONTROL_PRIO,
|
||||
&h_motor_turning_task_handle);
|
||||
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
@ -93,11 +97,10 @@ main(void)
|
|||
{
|
||||
stdio_usb_init();
|
||||
|
||||
sleep_ms(2000);
|
||||
sleep_ms(4000);
|
||||
printf("Test started!\n");
|
||||
|
||||
motor_init();
|
||||
set_wheel_direction(DIRECTION_LEFT_FORWARD | DIRECTION_RIGHT_FORWARD);
|
||||
|
||||
launch();
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ main (void)
|
|||
|
||||
line_sensor_setup();
|
||||
|
||||
init_ultrasonic();
|
||||
|
||||
initialize_car_state(); // TODO: Could be common functionality, To confirm
|
||||
// during Integration
|
||||
launch();
|
||||
|
|
|
@ -3,89 +3,15 @@
|
|||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRIG_PIN 0
|
||||
#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
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "ultrasonic_sensor.h"
|
||||
|
||||
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;
|
||||
xTaskCreate(distance_task,
|
||||
"TestDistThread",
|
||||
|
@ -94,8 +20,6 @@ vLaunch(void)
|
|||
1,
|
||||
&disttask);
|
||||
|
||||
// Start the tasks and timer running.
|
||||
//
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
|
@ -104,7 +28,7 @@ main(void)
|
|||
{
|
||||
stdio_init_all();
|
||||
init_ultrasonic();
|
||||
sleep_ms(3000);
|
||||
sleep_ms(1000);
|
||||
vLaunch();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -9,40 +9,73 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
vTaskDelay(500);
|
||||
vTaskDelay(1000);
|
||||
|
||||
// Trigger the ultrasonic sensor
|
||||
gpio_put(TRIG_PIN, 1);
|
||||
sleep_us(10); // Keep the trigger on for 10 microseconds
|
||||
sleep_us(10);
|
||||
gpio_put(TRIG_PIN, 0);
|
||||
|
||||
// Wait for the echo pulse to start
|
||||
while (gpio_get(ECHO_PIN) == 0)
|
||||
while (echo_rising)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
printf("Collision Imminent!\n");
|
||||
// Proc stop
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue