update webserver integration

This commit is contained in:
OldManSteve 2023-11-25 12:11:23 +08:00
parent 2cc7405e23
commit 7900df09e0
10 changed files with 405 additions and 298 deletions

View File

@ -33,6 +33,7 @@ target_link_libraries(rtos_car
hardware_adc
hardware_pwm
hardware_i2c
pico_lwip_http
)
pico_enable_stdio_usb(rtos_car 1)
pico_add_extra_outputs(rtos_car)

View File

@ -28,5 +28,10 @@ target_include_directories(frontend PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
target_compile_definitions(frontend PRIVATE
WIFI_SSID=\"${WIFI_SSID}\"
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
)
pico_enable_stdio_usb(frontend 1)
pico_add_extra_outputs(frontend)

View File

@ -2,6 +2,8 @@
#include "pico/cyw43_arch.h"
#include "stdio.h"
#include "car_config.h"
// CGI handler for start/stop car
const char * cgi_status_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
{
@ -12,9 +14,17 @@ const char * cgi_status_handler(int iIndex, int iNumParams, char *pcParam[], cha
if(strcmp(pcValue[0], "0") == 0){
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
printf("CAR STOP"); // call car stop func
/*
set_wheel_direction(DIRECTION_MASK);
set_wheel_speed_synced(0u, car_struct);
*/
}else if(strcmp(pcValue[0], "1") == 0){
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
printf("CAR START"); // call car start func
/*
set_wheel_direction(DIRECTION_FORWARD);
set_wheel_speed_synced(90u, car_struct);
*/
}
}
@ -54,7 +64,8 @@ static const tCGI cgi_handlers[] = {
},
};
void cgi_init(void)
void cgi_init(void *params)
{
car_struct_t *car_struct = (car_struct_t *)params;
http_set_cgi_handlers(cgi_handlers, 2);
}

View File

@ -1,71 +1,23 @@
#include "lwip/apps/httpd.h"
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwipopts.h"
#include "ssi.h"
#include "cgi.h"
#include "FreeRTOS.h"
#include "task.h"
// WIFI Credentials - take care if pushing to GitHub!
const char WIFI_SSID[] = "XXX";
const char WIFI_PASSWORD[] = "XXX";
#include "frontend.h"
#include "car_config.h"
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;
}
}
static void webserver_run(){
// 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) {
// Add any required delay or use other FreeRTOS features here if needed
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
static void webserver_task(){
if (cyw43_arch_init())
{
printf("failed to initialise\n");
return;
}
cyw43_arch_enable_sta_mode();
printf("Connecting to WiFi...\n");
// 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_ip_address();
webserver_run();
cyw43_arch_deinit();
}
int main() {
stdio_init_all();
// Create the FreeRTOS task for the web server
TaskHandle_t task_handle;
xTaskCreate(webserver_task, "WebServerTask", configMINIMAL_STACK_SIZE, NULL, 1, &task_handle);
obs_t obs;
motor_t motor_right;
motor_t motor_left;
motor_pid_t pid;
car_struct_t car_struct = { .p_right_motor = &motor_right,
.p_left_motor = &motor_left,
.p_pid = &pid,
.obs = &obs};
webserver_init(&car_struct);
// Start the FreeRTOS scheduler
vTaskStartScheduler();

75
frtos/frontend/frontend.h Normal file
View File

@ -0,0 +1,75 @@
#include "lwip/apps/httpd.h"
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwipopts.h"
#include "ssi.h"
#include "cgi.h"
#include "FreeRTOS.h"
#include "task.h"
#include "car_config.h"
// print assigned ip addr
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;
}
}
// initializes server and handlers
static void webserver_run(void *params){
car_struct_t *car_struct = (car_struct_t *)params;
// Initialize web server
httpd_init();
printf("Http server initialized\n");
// Configure SSI and CGI handler
ssi_init(&car_struct);
printf("SSI Handler initialized\n");
cgi_init(&car_struct);
printf("CGI Handler initialized\n");
// Infinite loop
while (1) {
// Add any required delay or use other FreeRTOS features here if needed
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
// webserver task connect wifi & start webserver_run
static void webserver_task(void *params){
car_struct_t *car_struct = (car_struct_t *)params;
if (cyw43_arch_init())
{
printf("failed to initialise\n");
return;
}
cyw43_arch_enable_sta_mode();
printf("Connecting to WiFi...\n");
// 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_ip_address();
webserver_run(&car_struct);
cyw43_arch_deinit();
}
// frontend initialize - create task
void webserver_init(void *params)
{
car_struct_t *car_struct = (car_struct_t *)params;
// Create the FreeRTOS task for the web server
TaskHandle_t task_handle;
xTaskCreate(webserver_task, "WebServerTask", configMINIMAL_STACK_SIZE, (void *)&car_struct, 1, &task_handle);
}

View File

@ -54,6 +54,11 @@
margin-top: 20px;
}
.obstacle-output {
font-size: 24px;
margin-top: 20px;
}
.orientation-output {
font-size: 24px;
margin-top: 20px;
@ -92,6 +97,9 @@
<div class="pid-output">
<p>PID Controller Output: <!--#pid--></p>
</div>
<div class="obstacle-output">
<p>Obstacle: <!--#obstacle--></p>
</div>
<div class="orientation-output">
<p>Orientation: <!--#orient--></p>
</div>

View File

@ -125,258 +125,279 @@ static const unsigned char data_index_shtml[] = {
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, 0x2E, 0x6F, 0x62, 0x73, 0x74, 0x61, 0x63, 0x6C,
0x65, 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, 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,
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,
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,
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, 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,
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, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74,
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, 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,
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, 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, 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, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A,
0x6F, 0x62, 0x73, 0x74, 0x61, 0x63, 0x6C, 0x65, 0x2D, 0x6F,
0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20,
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,
0x20, 0x3C, 0x70, 0x3E, 0x4F, 0x62, 0x73, 0x74, 0x61, 0x63,
0x6C, 0x65, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, 0x6F,
0x62, 0x73, 0x74, 0x61, 0x63, 0x6C, 0x65, 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, 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, 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, 0x44, 0x61, 0x74, 0x65, 0x2E, 0x6E, 0x6F, 0x77,
0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 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, 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, 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,
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,
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, 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, 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, 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, };
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 }};

Binary file not shown.

View File

@ -3,8 +3,11 @@
#include "hardware/adc.h"
#include "pico/stdlib.h"
#include "car_config.h"
car_struct_t *car_struct;
// SSI tags - tag length limited to 8 bytes by default
const char * ssi_tags[] = {"speed","barcode","pid","orient"};
const char * ssi_tags[] = {"speed","barcode","pid","obstacle","orient"};
u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
size_t printed;
@ -12,8 +15,15 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
case 0: // Speed
{
// call getSpeed() function
const float Speed = adc_read() * 3.3f / (1 << 12);
printed = snprintf(pcInsert, iInsertLen, "%f ",Speed);
/*
const float c_speed = car_struct->p_right_motor->speed.current_cms;
printf("\n\t%f\n",c_speed);
printed = snprintf(pcInsert, iInsertLen, "%f ",c_speed);
*/
const float speed = adc_read() * 3.3f / (1 << 12);
printed = snprintf(pcInsert, iInsertLen, "%f ",speed);
}
break;
case 1: // barcode
@ -26,13 +36,30 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
case 2: //PID
{
// whatever to display for PID
const char* PID = "54" ;
const char* PID = "-" ;
printed = snprintf(pcInsert, iInsertLen, "%s", PID);
}
break;
case 3: //Orientation
case 3: //Obstacle detected
{
// call getObstacleDetected() function
/*
bool obstacle = car_struct->obs->ultrasonic_detected;
if (obstacle){
printed = snprintf(pcInsert, iInsertLen, "%s", "YES");
}
else{
printed = snprintf(pcInsert, iInsertLen, "%s", "NO");
}
*/
printed = snprintf(pcInsert, iInsertLen, "%s", "YES");
}
case 4: //Orientation
{
// call getOrientation() function
const char* orien = "South";
printed = snprintf(pcInsert, iInsertLen, "%s", orien);
}
@ -46,7 +73,10 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
}
// Initialise the SSI handler
void ssi_init() {
void ssi_init(void *params) {
car_struct = (car_struct_t *)params;
// Initialise ADC (internal pin)
adc_init();
adc_set_temp_sensor_enabled(true);

View File

@ -3,6 +3,7 @@
#include "ultrasonic_sensor.h"
#include "car_config.h"
#include "motor_init.h"
#include "frontend.h"
/*!
* @brief Check if the car is on the line
@ -148,6 +149,9 @@ main(void)
.obs = &obs,
.p_direction = &direction };
// webserver frontend
webserver_init(&car_struct);
// Magnetometer
magnetometer_init(&car_struct);
// magnetometer_tasks_init(&car_struct);