Updated fileheaders and styled files using astyle.
This commit is contained in:
@@ -1,3 +1,32 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/app.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
|
||||
* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
|
||||
* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
|
||||
* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
|
||||
* 2015-04-25 timolang@gmail.com 416883c Pixy&Usb work with the new folder structure now.
|
||||
* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
|
||||
* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
|
||||
* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
|
||||
* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
|
||||
* 2015-04-27 timolang@gmail.com e249fb2 Added font support
|
||||
* 2015-04-27 timolang@gmail.com 7c9eabc Added button support.
|
||||
* 2015-04-27 timolang@gmail.com b300ac5 Added Checkbox support
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
|
||||
* 2015-05-12 aaron@duckpond.ch aec62d4 Added datasheets, updated touchsupport.
|
||||
* 2015-05-28 aaron@duckpond.ch 5bda699 implemented functions to get x and y coordinates and a test function
|
||||
* 2015-05-29 aaron@duckpond.ch 7d2d1a1 Implemented basic sampling and averaging of touch coordinates using timer7
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "app.h"
|
||||
#include "tft.h"
|
||||
#include "system.h"
|
||||
@@ -5,20 +34,20 @@
|
||||
#include "screen_main.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
void app_init() {
|
||||
system_init();
|
||||
tft_init();
|
||||
touch_init();
|
||||
filesystem_init();
|
||||
void app_init()
|
||||
{
|
||||
system_init();
|
||||
tft_init();
|
||||
touch_init();
|
||||
filesystem_init();
|
||||
|
||||
gui_screen_navigate(get_screen_main());
|
||||
gui_screen_navigate(get_screen_main());
|
||||
}
|
||||
|
||||
//app event loop
|
||||
void app_process() {
|
||||
|
||||
system_process(); //Let the system handle it's pending events
|
||||
gui_screen_update(); //update the currently active screen
|
||||
void app_process()
|
||||
{
|
||||
|
||||
system_process(); //Let the system handle it's pending events
|
||||
gui_screen_update(); //update the currently active screen
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/app.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
|
||||
* 2015-06-08 timolang@gmail.com 73db8b5 Added doxygen mainpage comment in app.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#ifndef APP_H
|
||||
#define APP_H
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\mainpage discoverpixy Doxygen Documentation
|
||||
Welcome to the code-documentation for all common (and plattformindependent) code. \n
|
||||
A good point to start is probably the <a href="modules.html">Modules</a> page.
|
||||
A good point to start is probably the <a href="modules.html">Modules</a> page.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/pixy_control.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-06-02 aaron@duckpond.ch e018a75 Implemented basic pi and pid controller
|
||||
* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
|
||||
* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
|
||||
* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
|
||||
* 2015-06-07 aaron@duckpond.ch 3d98ca9 Minor changes
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
/*
|
||||
* pixy_control.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/pixy_control.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-06-02 aaron@duckpond.ch e018a75 Implemented basic pi and pid controller
|
||||
* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
|
||||
* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
|
||||
* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#ifndef PIXY_CONTROL_H_
|
||||
#define PIXY_CONTROL_H_
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/pixy_frame.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "pixy_frame.h"
|
||||
#include "pixy.h"
|
||||
#include "tft.h"
|
||||
@@ -5,118 +18,113 @@
|
||||
|
||||
|
||||
|
||||
static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame);
|
||||
static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame);
|
||||
static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
|
||||
static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
|
||||
|
||||
|
||||
int pixy_render_full_frame(uint16_t x, uint16_t y) {
|
||||
return pixy_render_cropped_frame(x,y,0,0,320,200);
|
||||
}
|
||||
|
||||
|
||||
int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height) {
|
||||
uint8_t* videodata;
|
||||
int32_t response;
|
||||
int32_t fourccc;
|
||||
int8_t renderflags;
|
||||
uint16_t xwidth;
|
||||
uint16_t ywidth;
|
||||
uint32_t size;
|
||||
|
||||
|
||||
int return_value = pixy_command("cam_getFrame", // String id for remote procedure
|
||||
INT8(0x21), // mode
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
&fourccc,
|
||||
&renderflags,
|
||||
&xwidth,
|
||||
&ywidth,
|
||||
&size,
|
||||
&videodata, // pointer to mem address for returned frame
|
||||
END_IN_ARGS);
|
||||
|
||||
if(return_value==0) {
|
||||
return_value = renderBA81(x,y,xwidth,ywidth,size,videodata);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
int pixy_save_full_frame(FILE_HANDLE* handle) {
|
||||
return pixy_save_cropped_frame(handle,0,0,320,200);
|
||||
}
|
||||
|
||||
int pixy_save_cropped_frame(FILE_HANDLE* handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height) {
|
||||
uint8_t* videodata;
|
||||
int32_t response;
|
||||
int32_t fourccc;
|
||||
int8_t renderflags;
|
||||
uint16_t xwidth;
|
||||
uint16_t ywidth;
|
||||
uint32_t size;
|
||||
|
||||
|
||||
int return_value = pixy_command("cam_getFrame", // String id for remote procedure
|
||||
INT8(0x21), // mode
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
&fourccc,
|
||||
&renderflags,
|
||||
&xwidth,
|
||||
&ywidth,
|
||||
&size,
|
||||
&videodata, // pointer to mem address for returned frame
|
||||
END_IN_ARGS);
|
||||
|
||||
if(return_value==0) {
|
||||
return_value = saveBA81(handle,xwidth,ywidth,size,videodata);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t* r, uint8_t* g, uint8_t* b)
|
||||
int pixy_render_full_frame(uint16_t x, uint16_t y)
|
||||
{
|
||||
if (y&1)
|
||||
{
|
||||
if (x&1)
|
||||
{
|
||||
*r = *pixel;
|
||||
*g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2;
|
||||
*b = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = (*(pixel-1)+*(pixel+1))>>1;
|
||||
*g = *pixel;
|
||||
*b = (*(pixel-width)+*(pixel+width))>>1;
|
||||
}
|
||||
return pixy_render_cropped_frame(x, y, 0, 0, 320, 200);
|
||||
}
|
||||
|
||||
|
||||
int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
|
||||
{
|
||||
uint8_t* videodata;
|
||||
int32_t response;
|
||||
int32_t fourccc;
|
||||
int8_t renderflags;
|
||||
uint16_t xwidth;
|
||||
uint16_t ywidth;
|
||||
uint32_t size;
|
||||
|
||||
|
||||
int return_value = pixy_command("cam_getFrame", // String id for remote procedure
|
||||
INT8(0x21), // mode
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
&fourccc,
|
||||
&renderflags,
|
||||
&xwidth,
|
||||
&ywidth,
|
||||
&size,
|
||||
&videodata, // pointer to mem address for returned frame
|
||||
END_IN_ARGS);
|
||||
|
||||
if (return_value == 0) {
|
||||
return_value = renderBA81(x, y, xwidth, ywidth, size, videodata);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x&1)
|
||||
{
|
||||
*r = (*(pixel-width)+*(pixel+width))>>1;
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
int pixy_save_full_frame(FILE_HANDLE* handle)
|
||||
{
|
||||
return pixy_save_cropped_frame(handle, 0, 0, 320, 200);
|
||||
}
|
||||
|
||||
int pixy_save_cropped_frame(FILE_HANDLE* handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
|
||||
{
|
||||
uint8_t* videodata;
|
||||
int32_t response;
|
||||
int32_t fourccc;
|
||||
int8_t renderflags;
|
||||
uint16_t xwidth;
|
||||
uint16_t ywidth;
|
||||
uint32_t size;
|
||||
|
||||
|
||||
int return_value = pixy_command("cam_getFrame", // String id for remote procedure
|
||||
INT8(0x21), // mode
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
&fourccc,
|
||||
&renderflags,
|
||||
&xwidth,
|
||||
&ywidth,
|
||||
&size,
|
||||
&videodata, // pointer to mem address for returned frame
|
||||
END_IN_ARGS);
|
||||
|
||||
if (return_value == 0) {
|
||||
return_value = saveBA81(handle, xwidth, ywidth, size, videodata);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t* pixel, uint8_t* r, uint8_t* g, uint8_t* b)
|
||||
{
|
||||
if (y & 1) {
|
||||
if (x & 1) {
|
||||
*r = *pixel;
|
||||
*g = (*(pixel - 1) + * (pixel + 1) + * (pixel + width) + * (pixel - width)) >> 2;
|
||||
*b = (*(pixel - width - 1) + * (pixel - width + 1) + * (pixel + width - 1) + * (pixel + width + 1)) >> 2;
|
||||
} else {
|
||||
*r = (*(pixel - 1) + * (pixel + 1)) >> 1;
|
||||
*g = *pixel;
|
||||
*b = (*(pixel-1)+*(pixel+1))>>1;
|
||||
*b = (*(pixel - width) + * (pixel + width)) >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2;
|
||||
*g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2;
|
||||
} else {
|
||||
if (x & 1) {
|
||||
*r = (*(pixel - width) + * (pixel + width)) >> 1;
|
||||
*g = *pixel;
|
||||
*b = (*(pixel - 1) + * (pixel + 1)) >> 1;
|
||||
} else {
|
||||
*r = (*(pixel - width - 1) + * (pixel - width + 1) + * (pixel + width - 1) + * (pixel + width + 1)) >> 2;
|
||||
*g = (*(pixel - 1) + * (pixel + 1) + * (pixel + width) + * (pixel - width)) >> 2;
|
||||
*b = *pixel;
|
||||
}
|
||||
}
|
||||
@@ -128,7 +136,7 @@ static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pi
|
||||
|
||||
|
||||
|
||||
static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
|
||||
static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame)
|
||||
{
|
||||
uint16_t x, y;
|
||||
uint8_t r, g, b;
|
||||
@@ -140,102 +148,101 @@ static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t hei
|
||||
// don't render top and bottom rows, and left and rightmost columns because of color
|
||||
// interpolation
|
||||
//uint32_t decodedimage[(width-2)*(height-2)];
|
||||
uint16_t* decodedimage = malloc(sizeof(uint16_t)*(width-2)*(height-2));
|
||||
uint16_t* decodedimage = malloc(sizeof(uint16_t) * (width - 2) * (height - 2));
|
||||
|
||||
if(decodedimage==NULL) { //not enough free space to decode image in memory
|
||||
if (decodedimage == NULL) { //not enough free space to decode image in memory
|
||||
//decode & render image pixel by pixel
|
||||
for (y=1; y<height-1; y++)
|
||||
{
|
||||
frame++;
|
||||
for (x=1; x<width-1; x++, frame++)
|
||||
{
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
tft_draw_pixel(xpos+x-1,ypos+y-1,RGB(r,g,b));
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
} else { //enough space
|
||||
uint16_t* line = decodedimage;
|
||||
for (y=1; y<height-1; y++)
|
||||
{
|
||||
//line = (unsigned int *)img.scanLine(y-1);
|
||||
frame++;
|
||||
for (x=1; x<width-1; x++, frame++)
|
||||
{
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
//*line++ = (0xff<<24) | (r<<16) | (g<<8) | (b<<0);
|
||||
*line++ = RGB(r,g,b);
|
||||
}
|
||||
frame++;
|
||||
for (y = 1; y < height - 1; y++) {
|
||||
frame++;
|
||||
|
||||
for (x = 1; x < width - 1; x++, frame++) {
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
tft_draw_pixel(xpos + x - 1, ypos + y - 1, RGB(r, g, b));
|
||||
}
|
||||
|
||||
tft_draw_bitmap_unscaled(xpos,ypos,width-2,height-2,decodedimage);
|
||||
frame++;
|
||||
}
|
||||
} else { //enough space
|
||||
uint16_t* line = decodedimage;
|
||||
|
||||
free(decodedimage);
|
||||
for (y = 1; y < height - 1; y++) {
|
||||
//line = (unsigned int *)img.scanLine(y-1);
|
||||
frame++;
|
||||
|
||||
for (x = 1; x < width - 1; x++, frame++) {
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
//*line++ = (0xff<<24) | (r<<16) | (g<<8) | (b<<0);
|
||||
*line++ = RGB(r, g, b);
|
||||
}
|
||||
|
||||
frame++;
|
||||
}
|
||||
|
||||
tft_draw_bitmap_unscaled(xpos, ypos, width - 2, height - 2, decodedimage);
|
||||
|
||||
free(decodedimage);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
|
||||
static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame)
|
||||
{
|
||||
uint16_t x, y;
|
||||
uint8_t r, g, b;
|
||||
|
||||
uint32_t fpos = handle->fpos;
|
||||
uint32_t row_size_padded = ((width-2)*3 + 3) & (~3); //row size aligned to 4 bytes
|
||||
uint32_t fpos_end = fpos + row_size_padded* (height-2);
|
||||
uint32_t row_size_padded = ((width - 2) * 3 + 3) & (~3); //row size aligned to 4 bytes
|
||||
uint32_t fpos_end = fpos + row_size_padded * (height - 2);
|
||||
|
||||
|
||||
// skip first line
|
||||
frame += width;
|
||||
|
||||
// don't render top and bottom rows, and left and rightmost columns because of color
|
||||
// interpolation
|
||||
// interpolation
|
||||
|
||||
for (y=1; y<height-1; y++)
|
||||
{
|
||||
frame++;
|
||||
uint8_t rowbuf[row_size_padded];
|
||||
for (y = 1; y < height - 1; y++) {
|
||||
frame++;
|
||||
uint8_t rowbuf[row_size_padded];
|
||||
|
||||
//Bitmaps are saved "bottom-up". Seek to the right row.
|
||||
if(filesystem_file_seek(handle,fpos_end-row_size_padded*y)!=F_OK) {
|
||||
return -1;
|
||||
}
|
||||
//Bitmaps are saved "bottom-up". Seek to the right row.
|
||||
if (filesystem_file_seek(handle, fpos_end - row_size_padded * y) != F_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (x=1; x<width-1; x++, frame++)
|
||||
{
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
//bitmaps are saved in 24bit b,g,r format
|
||||
rowbuf[(x-1)*3] = b;
|
||||
rowbuf[(x-1)*3+1] = g;
|
||||
rowbuf[(x-1)*3+2] = r;
|
||||
}
|
||||
for (x = 1; x < width - 1; x++, frame++) {
|
||||
interpolateBayer(width, x, y, frame, &r, &g, &b);
|
||||
//bitmaps are saved in 24bit b,g,r format
|
||||
rowbuf[(x - 1) * 3] = b;
|
||||
rowbuf[(x - 1) * 3 + 1] = g;
|
||||
rowbuf[(x - 1) * 3 + 2] = r;
|
||||
}
|
||||
|
||||
if(filesystem_file_write(handle,rowbuf,row_size_padded)!=F_OK) {
|
||||
return -1;
|
||||
}
|
||||
if (filesystem_file_write(handle, rowbuf, row_size_padded) != F_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
frame++;
|
||||
}
|
||||
return 0;
|
||||
frame++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pixy_cc_set_region(uint8_t signum, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height) {
|
||||
int32_t response;
|
||||
int pixy_cc_set_region(uint8_t signum, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
|
||||
{
|
||||
int32_t response;
|
||||
|
||||
int return_value = pixy_command("cc_setSigRegion", // String id for remote procedure
|
||||
INT32(0), // type = normal color code
|
||||
INT8(signum),
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
END_IN_ARGS);
|
||||
return return_value;
|
||||
int return_value = pixy_command("cc_setSigRegion", // String id for remote procedure
|
||||
INT32(0), // type = normal color code
|
||||
INT8(signum),
|
||||
INT16(xoffset), // xoffset
|
||||
INT16(yoffset), // yoffset
|
||||
INT16(width), // width
|
||||
INT16(height), // height
|
||||
END_OUT_ARGS, // separator
|
||||
&response, // pointer to mem address for return value
|
||||
END_IN_ARGS);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/pixy_frame.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#ifndef PIXY_FRAME_H
|
||||
#define PIXY_FRAME_H
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_filetest.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
|
||||
* 2015-05-10 timolang@gmail.com 790f602 Added bitmap decoding/drawing example
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
|
||||
* 2015-05-15 timolang@gmail.com 85f1aee Changed filetest to use new bitmap draw method.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_filetest.h"
|
||||
#include "button.h"
|
||||
#include "tft.h"
|
||||
@@ -7,133 +24,132 @@
|
||||
|
||||
static BUTTON_STRUCT b_back;
|
||||
|
||||
static void b_back_cb(void* button) {
|
||||
gui_screen_back();
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
gui_screen_back();
|
||||
}
|
||||
|
||||
|
||||
static void image_test();
|
||||
|
||||
static void enter(void* screen) {
|
||||
tft_clear(HEX(0xBABECD));
|
||||
|
||||
//Back button
|
||||
b_back.base.x1=10; //Start X of Button
|
||||
b_back.base.y1=200; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //b_back.base.x1+160; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(HEX(0xBABECD));
|
||||
|
||||
//Back button
|
||||
b_back.base.x1 = 10; //Start X of Button
|
||||
b_back.base.y1 = 200; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //b_back.base.x1+160; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
/*
|
||||
//tft test
|
||||
tft_draw_pixel(0,0,BLACK);
|
||||
tft_draw_pixel(319,239,BLACK);
|
||||
tft_draw_pixel(10,210,BLUE);
|
||||
tft_draw_pixel(12,210,BLUE);
|
||||
tft_draw_rectangle(40,100,60,235,BLUE);
|
||||
tft_fill_rectangle(100,215,200,225,GREEN);
|
||||
tft_draw_line(10,50,310,225,RGB(0xFF,0,0xFF));
|
||||
tft_draw_circle(10,10,100, RED);
|
||||
tft_print_line(30, 130, RED, BLUE, 0, "Hallo");
|
||||
*/
|
||||
tft_draw_line(10, 30, 310, 30, BLACK);
|
||||
tft_print_line(10, 18, BLUE, TRANSPARENT, 0, "Name D H RO Date Time Size");
|
||||
|
||||
tft_draw_line(10,30,310,30,BLACK);
|
||||
tft_print_line(10,18,BLUE,TRANSPARENT,0,"Name D H RO Date Time Size");
|
||||
|
||||
int y = 33;
|
||||
|
||||
DIRECTORY_STRUCT* dir = filesystem_dir_open(".");
|
||||
if(dir==NULL) return;
|
||||
int y = 33;
|
||||
|
||||
for(int i=0; i<dir->num_files; i++) {
|
||||
FILE_STRUCT* file = &(dir->files[i]);
|
||||
tft_print_formatted(10,y,
|
||||
(file->fattrib&F_DIR)?GREEN:RED,
|
||||
TRANSPARENT,0,"%-13s%c %c %s %02u%02u%02u %02u:%02u:%02u %u",
|
||||
file->fname,
|
||||
(file->fattrib&F_DIR)?'D':' ',
|
||||
(file->fattrib&F_HID)?'H':' ',
|
||||
(file->fattrib&F_RDO)?"R ":"RW",
|
||||
file->fdate.day,
|
||||
file->fdate.month,
|
||||
(file->fdate.year+1980)%100,
|
||||
file->ftime.hour,
|
||||
file->ftime.min,
|
||||
file->ftime.sec*2,
|
||||
file->fsize);
|
||||
y+=14;
|
||||
}
|
||||
DIRECTORY_STRUCT* dir = filesystem_dir_open(".");
|
||||
|
||||
filesystem_dir_close(dir);
|
||||
if (dir == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
y+=14;
|
||||
for (int i = 0; i < dir->num_files; i++) {
|
||||
FILE_STRUCT* file = &(dir->files[i]);
|
||||
tft_print_formatted(10, y,
|
||||
(file->fattrib & F_DIR) ? GREEN : RED,
|
||||
TRANSPARENT, 0, "%-13s%c %c %s %02u%02u%02u %02u:%02u:%02u %u",
|
||||
file->fname,
|
||||
(file->fattrib & F_DIR) ? 'D' : ' ',
|
||||
(file->fattrib & F_HID) ? 'H' : ' ',
|
||||
(file->fattrib & F_RDO) ? "R " : "RW",
|
||||
file->fdate.day,
|
||||
file->fdate.month,
|
||||
(file->fdate.year + 1980) % 100,
|
||||
file->ftime.hour,
|
||||
file->ftime.min,
|
||||
file->ftime.sec * 2,
|
||||
file->fsize);
|
||||
y += 14;
|
||||
}
|
||||
|
||||
FILE_HANDLE* file = filesystem_file_open("test.txt");
|
||||
if(file==NULL) {
|
||||
tft_print_line(10,y,BLUE,TRANSPARENT,0,"Could not open test.txt");
|
||||
} else {
|
||||
char buf [30];
|
||||
int size = (file->fsize>30)?29:file->fsize-1;
|
||||
FILE_STATUS st = filesystem_file_read(file,buf,size);
|
||||
|
||||
if(st==F_OK) {
|
||||
buf[file->fpos]='\0';
|
||||
tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"test.txt contains \"%s\"",buf);
|
||||
long num = strtol(&(buf[file->fpos-4]),NULL,0);
|
||||
num++;
|
||||
|
||||
y+=14;
|
||||
|
||||
if(filesystem_file_seek(file,file->fpos-4)!=F_OK) {
|
||||
tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"Could not seek to %d",file->fpos-4);
|
||||
} else {
|
||||
sprintf(buf,"%04d",num);
|
||||
if(filesystem_file_write(file,buf,4) != F_OK) {
|
||||
tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"Could not write new number %d",num);
|
||||
} else {
|
||||
tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"New number written %d",num);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tft_print_line(10,y,BLUE,TRANSPARENT,0,"Could not read from test.txt");
|
||||
}
|
||||
filesystem_dir_close(dir);
|
||||
|
||||
}
|
||||
filesystem_file_close(file);
|
||||
y += 14;
|
||||
|
||||
image_test();
|
||||
FILE_HANDLE* file = filesystem_file_open("test.txt");
|
||||
|
||||
if (file == NULL) {
|
||||
tft_print_line(10, y, BLUE, TRANSPARENT, 0, "Could not open test.txt");
|
||||
} else {
|
||||
char buf [30];
|
||||
int size = (file->fsize > 30) ? 29 : file->fsize - 1;
|
||||
FILE_STATUS st = filesystem_file_read(file, buf, size);
|
||||
|
||||
if (st == F_OK) {
|
||||
buf[file->fpos] = '\0';
|
||||
tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "test.txt contains \"%s\"", buf);
|
||||
long num = strtol(&(buf[file->fpos - 4]), NULL, 0);
|
||||
num++;
|
||||
|
||||
y += 14;
|
||||
|
||||
if (filesystem_file_seek(file, file->fpos - 4) != F_OK) {
|
||||
tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "Could not seek to %d", file->fpos - 4);
|
||||
} else {
|
||||
sprintf(buf, "%04d", num);
|
||||
|
||||
if (filesystem_file_write(file, buf, 4) != F_OK) {
|
||||
tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "Could not write new number %d", num);
|
||||
} else {
|
||||
tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "New number written %d", num);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tft_print_line(10, y, BLUE, TRANSPARENT, 0, "Could not read from test.txt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
filesystem_file_close(file);
|
||||
|
||||
image_test();
|
||||
}
|
||||
|
||||
static void leave(void* screen) {
|
||||
gui_button_remove(&b_back);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
gui_button_remove(&b_back);
|
||||
}
|
||||
|
||||
static void update(void* screen) {
|
||||
static void update(void* screen)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_filetest() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_filetest()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
static void image_test() {
|
||||
static void image_test()
|
||||
{
|
||||
|
||||
|
||||
if(!tft_draw_bitmap_file_unscaled(250,170,"cpu.bmp")) {
|
||||
tft_print_line(10,180,BLUE,TRANSPARENT,0,"Could not open cpu.bmp");
|
||||
}
|
||||
tft_draw_rectangle(250-1,170-1,250-1+64,170-1+64,BLACK);
|
||||
if (!tft_draw_bitmap_file_unscaled(250, 170, "cpu.bmp")) {
|
||||
tft_print_line(10, 180, BLUE, TRANSPARENT, 0, "Could not open cpu.bmp");
|
||||
}
|
||||
|
||||
tft_draw_rectangle(250 - 1, 170 - 1, 250 - 1 + 64, 170 - 1 + 64, BLACK);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_filetest.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_guitest.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
|
||||
* 2015-05-09 timolang@gmail.com c652b6b Improved Emulator Gui
|
||||
* 2015-05-29 aaron@duckpond.ch 7d2d1a1 Implemented basic sampling and averaging of touch coordinates using timer7
|
||||
* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
|
||||
* 2015-06-02 timolang@gmail.com da34bce Fixed all printf related problems on discovery using workarounds and newlib nano-instead of newlib
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_guitest.h"
|
||||
#include "button.h"
|
||||
#include "tft.h"
|
||||
@@ -9,127 +27,138 @@ static TOUCH_AREA_STRUCT a_area;
|
||||
static CHECKBOX_STRUCT c_cbox;
|
||||
static NUMUPDOWN_STRUCT n_updown;
|
||||
|
||||
static void checkboxCB(void *checkbox, bool checked) {
|
||||
printf("Checkbox %s\n",(checked?"checked":"unchecked"));
|
||||
static void checkboxCB(void* checkbox, bool checked)
|
||||
{
|
||||
printf("Checkbox %s\n", (checked ? "checked" : "unchecked"));
|
||||
}
|
||||
|
||||
static void b_back_cb(void* button) {
|
||||
gui_screen_back();
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
gui_screen_back();
|
||||
}
|
||||
|
||||
static void n_updown_cb(void* numupdown, int16_t value) {
|
||||
printf("New NumUpDown Value %d\n",value);
|
||||
static void n_updown_cb(void* numupdown, int16_t value)
|
||||
{
|
||||
printf("New NumUpDown Value %d\n", value);
|
||||
}
|
||||
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
|
||||
|
||||
switch(triggeredAction) {
|
||||
case PEN_DOWN:
|
||||
printf("action PEN_DOWN\n");
|
||||
break;
|
||||
case PEN_UP:
|
||||
printf("action PEN_UP\n");
|
||||
break;
|
||||
case PEN_MOVE:
|
||||
printf("action PEN_MOVE\n");
|
||||
break;
|
||||
case PEN_ENTER:
|
||||
printf("action PEN_ENTER\n");
|
||||
break;
|
||||
case PEN_LEAVE:
|
||||
printf("action PEN_LEAVE\n");
|
||||
break;
|
||||
default:
|
||||
printf("action %s\n",triggeredAction);
|
||||
break;
|
||||
}
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
|
||||
{
|
||||
|
||||
switch (triggeredAction) {
|
||||
case PEN_DOWN:
|
||||
printf("action PEN_DOWN\n");
|
||||
break;
|
||||
|
||||
case PEN_UP:
|
||||
printf("action PEN_UP\n");
|
||||
break;
|
||||
|
||||
case PEN_MOVE:
|
||||
printf("action PEN_MOVE\n");
|
||||
break;
|
||||
|
||||
case PEN_ENTER:
|
||||
printf("action PEN_ENTER\n");
|
||||
break;
|
||||
|
||||
case PEN_LEAVE:
|
||||
printf("action PEN_LEAVE\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("action %s\n", triggeredAction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void enter(void* screen) {
|
||||
tft_clear(HEX(0xA6FD9A));
|
||||
|
||||
//Back button
|
||||
b_back.base.x1=10; //Start X of Button
|
||||
b_back.base.y1=10; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //b_back.base.x1+160; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(HEX(0xA6FD9A));
|
||||
|
||||
//Back button
|
||||
b_back.base.x1 = 10; //Start X of Button
|
||||
b_back.base.y1 = 10; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //b_back.base.x1+160; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
|
||||
//tft test
|
||||
tft_draw_pixel(0,0,BLACK);
|
||||
tft_draw_pixel(319,239,BLACK);
|
||||
tft_draw_pixel(10,210,BLUE);
|
||||
tft_draw_pixel(12,210,BLUE);
|
||||
tft_draw_rectangle(40,100,60,235,BLUE);
|
||||
tft_fill_rectangle(100,215,200,225,GREEN);
|
||||
tft_draw_line(10,50,310,225,RGB(0xFF,0,0xFF));
|
||||
tft_draw_circle(10,10,100, RED);
|
||||
tft_print_line(30, 130, RED, BLUE, 0, "Hallo");
|
||||
|
||||
|
||||
|
||||
//Area test
|
||||
a_area.hookedActions = PEN_DOWN | PEN_UP | PEN_MOVE | PEN_ENTER | PEN_LEAVE;
|
||||
a_area.x1 = 130;
|
||||
a_area.y1 = 30;
|
||||
a_area.x2 = 200;
|
||||
a_area.y2 = 60;
|
||||
a_area.callback = touchCB;
|
||||
touch_register_area(&a_area);
|
||||
//tft test
|
||||
tft_draw_pixel(0, 0, BLACK);
|
||||
tft_draw_pixel(319, 239, BLACK);
|
||||
tft_draw_pixel(10, 210, BLUE);
|
||||
tft_draw_pixel(12, 210, BLUE);
|
||||
tft_draw_rectangle(40, 100, 60, 235, BLUE);
|
||||
tft_fill_rectangle(100, 215, 200, 225, GREEN);
|
||||
tft_draw_line(10, 50, 310, 225, RGB(0xFF, 0, 0xFF));
|
||||
tft_draw_circle(10, 10, 100, RED);
|
||||
tft_print_line(30, 130, RED, BLUE, 0, "Hallo");
|
||||
|
||||
|
||||
|
||||
//Checkbox test
|
||||
c_cbox.base.x1=220;
|
||||
c_cbox.base.y1=45;
|
||||
c_cbox.base.x2=c_cbox.base.x1+16;
|
||||
c_cbox.base.y2=c_cbox.base.y1+16;
|
||||
c_cbox.fgcolor = GREEN;
|
||||
c_cbox.checked = true;
|
||||
c_cbox.callback = checkboxCB;
|
||||
gui_checkbox_add(&c_cbox);
|
||||
|
||||
//Area test
|
||||
a_area.hookedActions = PEN_DOWN | PEN_UP | PEN_MOVE | PEN_ENTER | PEN_LEAVE;
|
||||
a_area.x1 = 130;
|
||||
a_area.y1 = 30;
|
||||
a_area.x2 = 200;
|
||||
a_area.y2 = 60;
|
||||
a_area.callback = touchCB;
|
||||
touch_register_area(&a_area);
|
||||
|
||||
//Num up down test
|
||||
n_updown.x=200;
|
||||
n_updown.y=120;
|
||||
n_updown.fgcolor=RED;
|
||||
n_updown.value = -3;
|
||||
n_updown.max=11;
|
||||
n_updown.min =-5;
|
||||
n_updown.callback=n_updown_cb;
|
||||
gui_numupdown_add(&n_updown);
|
||||
|
||||
|
||||
//Checkbox test
|
||||
c_cbox.base.x1 = 220;
|
||||
c_cbox.base.y1 = 45;
|
||||
c_cbox.base.x2 = c_cbox.base.x1 + 16;
|
||||
c_cbox.base.y2 = c_cbox.base.y1 + 16;
|
||||
c_cbox.fgcolor = GREEN;
|
||||
c_cbox.checked = true;
|
||||
c_cbox.callback = checkboxCB;
|
||||
gui_checkbox_add(&c_cbox);
|
||||
|
||||
|
||||
//Num up down test
|
||||
n_updown.x = 200;
|
||||
n_updown.y = 120;
|
||||
n_updown.fgcolor = RED;
|
||||
n_updown.value = -3;
|
||||
n_updown.max = 11;
|
||||
n_updown.min = -5;
|
||||
n_updown.callback = n_updown_cb;
|
||||
gui_numupdown_add(&n_updown);
|
||||
|
||||
}
|
||||
|
||||
static void leave(void* screen) {
|
||||
gui_button_remove(&b_back);
|
||||
gui_checkbox_remove(&c_cbox);
|
||||
gui_numupdown_remove(&n_updown);
|
||||
touch_unregister_area(&a_area);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
gui_button_remove(&b_back);
|
||||
gui_checkbox_remove(&c_cbox);
|
||||
gui_numupdown_remove(&n_updown);
|
||||
touch_unregister_area(&a_area);
|
||||
}
|
||||
|
||||
static void update(void* screen) {
|
||||
//gui_button_redraw(&b_back); //only needed if button is overdrawn by others
|
||||
//.... for the other elements as well
|
||||
static void update(void* screen)
|
||||
{
|
||||
//gui_button_redraw(&b_back); //only needed if button is overdrawn by others
|
||||
//.... for the other elements as well
|
||||
}
|
||||
|
||||
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_guitest() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_guitest()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_guitest.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_main.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
|
||||
* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
|
||||
* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
|
||||
* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
|
||||
* 2015-06-01 timolang@gmail.com 3155f42 Fixed mainscreen layout.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_main.h"
|
||||
#include "screen_guitest.h"
|
||||
#include "screen_pixytest.h"
|
||||
@@ -17,157 +35,165 @@ BUTTON_STRUCT b_ref_tracking;
|
||||
BUTTON_STRUCT b_photo_mode;
|
||||
|
||||
|
||||
static void b_our_tracking_cb(void* button) {
|
||||
tracking_set_mode(OUR_TRACKING);
|
||||
gui_screen_navigate(get_screen_tracking());
|
||||
static void b_our_tracking_cb(void* button)
|
||||
{
|
||||
tracking_set_mode(OUR_TRACKING);
|
||||
gui_screen_navigate(get_screen_tracking());
|
||||
}
|
||||
|
||||
static void b_ref_tracking_cb(void* button) {
|
||||
tracking_set_mode(REFERENCE_TRACKING);
|
||||
gui_screen_navigate(get_screen_tracking());
|
||||
static void b_ref_tracking_cb(void* button)
|
||||
{
|
||||
tracking_set_mode(REFERENCE_TRACKING);
|
||||
gui_screen_navigate(get_screen_tracking());
|
||||
}
|
||||
|
||||
static void b_photo_mode_cb(void* button) {
|
||||
gui_screen_navigate(get_screen_photomode());
|
||||
static void b_photo_mode_cb(void* button)
|
||||
{
|
||||
gui_screen_navigate(get_screen_photomode());
|
||||
}
|
||||
|
||||
static void b_guitest_cb(void* button) {
|
||||
gui_screen_navigate(get_screen_guitest());
|
||||
static void b_guitest_cb(void* button)
|
||||
{
|
||||
gui_screen_navigate(get_screen_guitest());
|
||||
}
|
||||
|
||||
static void b_filetest_cb(void* button) {
|
||||
gui_screen_navigate(get_screen_filetest());
|
||||
static void b_filetest_cb(void* button)
|
||||
{
|
||||
gui_screen_navigate(get_screen_filetest());
|
||||
}
|
||||
|
||||
static void b_pixytest_cb(void* button) {
|
||||
gui_screen_navigate(get_screen_pixytest());
|
||||
static void b_pixytest_cb(void* button)
|
||||
{
|
||||
gui_screen_navigate(get_screen_pixytest());
|
||||
}
|
||||
|
||||
|
||||
static void enter(void* screen) {
|
||||
tft_clear(WHITE);
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(WHITE);
|
||||
|
||||
//Heading
|
||||
tft_print_line(10,10,BLUE,TRANSPARENT,1,"Discoverpixy");
|
||||
tft_draw_line(0,40,319,40,BLACK);
|
||||
//Heading
|
||||
tft_print_line(10, 10, BLUE, TRANSPARENT, 1, "Discoverpixy");
|
||||
tft_draw_line(0, 40, 319, 40, BLACK);
|
||||
|
||||
#define X_TAB 97
|
||||
#define BUTTON_SPACING 7
|
||||
#define X_TAB 97
|
||||
#define BUTTON_SPACING 7
|
||||
|
||||
//First line of buttons
|
||||
#define Y_FIRST 60
|
||||
tft_print_line(10,Y_FIRST,BLACK,TRANSPARENT,0,"Tracking:");
|
||||
//First line of buttons
|
||||
#define Y_FIRST 60
|
||||
tft_print_line(10, Y_FIRST, BLACK, TRANSPARENT, 0, "Tracking:");
|
||||
|
||||
b_our_tracking.base.x1=X_TAB; //Start X of Button
|
||||
b_our_tracking.base.y1=Y_FIRST-3; //Start Y of Button
|
||||
b_our_tracking.base.x2=AUTO; //Auto Calculate X2 with String Width
|
||||
b_our_tracking.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_our_tracking.txtcolor=WHITE; //Set foreground color
|
||||
b_our_tracking.bgcolor=HEX(0xE30535); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_our_tracking.font=0; //Select Font
|
||||
b_our_tracking.text="Our Tracking"; //Set Text (For formatted strings take sprintf)
|
||||
b_our_tracking.callback=b_our_tracking_cb; //Call b_our_tracking when the button get's pressed
|
||||
gui_button_add(&b_our_tracking); //Register Button (and run the callback from now on)
|
||||
b_our_tracking.base.x1 = X_TAB; //Start X of Button
|
||||
b_our_tracking.base.y1 = Y_FIRST - 3; //Start Y of Button
|
||||
b_our_tracking.base.x2 = AUTO; //Auto Calculate X2 with String Width
|
||||
b_our_tracking.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_our_tracking.txtcolor = WHITE; //Set foreground color
|
||||
b_our_tracking.bgcolor = HEX(0xE30535); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_our_tracking.font = 0; //Select Font
|
||||
b_our_tracking.text = "Our Tracking"; //Set Text (For formatted strings take sprintf)
|
||||
b_our_tracking.callback = b_our_tracking_cb; //Call b_our_tracking when the button get's pressed
|
||||
gui_button_add(&b_our_tracking); //Register Button (and run the callback from now on)
|
||||
|
||||
|
||||
b_ref_tracking.base.x1=b_our_tracking.base.x2+BUTTON_SPACING;
|
||||
b_ref_tracking.base.y1=Y_FIRST-3;
|
||||
b_ref_tracking.base.x2=AUTO;
|
||||
b_ref_tracking.base.y2=AUTO;
|
||||
b_ref_tracking.txtcolor=WHITE;
|
||||
b_ref_tracking.bgcolor=HEX(0xFF2151);
|
||||
b_ref_tracking.font=0;
|
||||
b_ref_tracking.text="Ref Tracking";
|
||||
b_ref_tracking.callback=b_ref_tracking_cb;
|
||||
gui_button_add(&b_ref_tracking);
|
||||
b_ref_tracking.base.x1 = b_our_tracking.base.x2 + BUTTON_SPACING;
|
||||
b_ref_tracking.base.y1 = Y_FIRST - 3;
|
||||
b_ref_tracking.base.x2 = AUTO;
|
||||
b_ref_tracking.base.y2 = AUTO;
|
||||
b_ref_tracking.txtcolor = WHITE;
|
||||
b_ref_tracking.bgcolor = HEX(0xFF2151);
|
||||
b_ref_tracking.font = 0;
|
||||
b_ref_tracking.text = "Ref Tracking";
|
||||
b_ref_tracking.callback = b_ref_tracking_cb;
|
||||
gui_button_add(&b_ref_tracking);
|
||||
|
||||
//Second line of buttons
|
||||
#define Y_SECOND Y_FIRST+25
|
||||
tft_print_line(10,Y_SECOND,BLACK,TRANSPARENT,0,"Photo mode:");
|
||||
//Second line of buttons
|
||||
#define Y_SECOND Y_FIRST+25
|
||||
tft_print_line(10, Y_SECOND, BLACK, TRANSPARENT, 0, "Photo mode:");
|
||||
|
||||
b_photo_mode.base.x1=X_TAB;
|
||||
b_photo_mode.base.y1=Y_SECOND-3;
|
||||
b_photo_mode.base.x2=AUTO;
|
||||
b_photo_mode.base.y2=AUTO;
|
||||
b_photo_mode.txtcolor=WHITE;
|
||||
b_photo_mode.bgcolor=HEX(0x21B1FF);
|
||||
b_photo_mode.font=0;
|
||||
b_photo_mode.text="Photo Mode";
|
||||
b_photo_mode.callback=b_photo_mode_cb;
|
||||
gui_button_add(&b_photo_mode);
|
||||
b_photo_mode.base.x1 = X_TAB;
|
||||
b_photo_mode.base.y1 = Y_SECOND - 3;
|
||||
b_photo_mode.base.x2 = AUTO;
|
||||
b_photo_mode.base.y2 = AUTO;
|
||||
b_photo_mode.txtcolor = WHITE;
|
||||
b_photo_mode.bgcolor = HEX(0x21B1FF);
|
||||
b_photo_mode.font = 0;
|
||||
b_photo_mode.text = "Photo Mode";
|
||||
b_photo_mode.callback = b_photo_mode_cb;
|
||||
gui_button_add(&b_photo_mode);
|
||||
|
||||
|
||||
//Third line of buttons
|
||||
#define Y_THIRD Y_SECOND+25
|
||||
tft_print_line(10,Y_THIRD,BLACK,TRANSPARENT,0,"Tests:");
|
||||
//Third line of buttons
|
||||
#define Y_THIRD Y_SECOND+25
|
||||
tft_print_line(10, Y_THIRD, BLACK, TRANSPARENT, 0, "Tests:");
|
||||
|
||||
b_guitest.base.x1=X_TAB;
|
||||
b_guitest.base.y1=Y_THIRD-3;
|
||||
b_guitest.base.x2=AUTO;
|
||||
b_guitest.base.y2=AUTO;
|
||||
b_guitest.txtcolor=BLACK;
|
||||
b_guitest.bgcolor=HEX(0x00FA21);
|
||||
b_guitest.font=0;
|
||||
b_guitest.text="Gui & Tft";
|
||||
b_guitest.callback=b_guitest_cb;
|
||||
gui_button_add(&b_guitest);
|
||||
b_guitest.base.x1 = X_TAB;
|
||||
b_guitest.base.y1 = Y_THIRD - 3;
|
||||
b_guitest.base.x2 = AUTO;
|
||||
b_guitest.base.y2 = AUTO;
|
||||
b_guitest.txtcolor = BLACK;
|
||||
b_guitest.bgcolor = HEX(0x00FA21);
|
||||
b_guitest.font = 0;
|
||||
b_guitest.text = "Gui & Tft";
|
||||
b_guitest.callback = b_guitest_cb;
|
||||
gui_button_add(&b_guitest);
|
||||
|
||||
|
||||
b_pixytest.base.x1=b_guitest.base.x2+BUTTON_SPACING;
|
||||
b_pixytest.base.y1=Y_THIRD-3;
|
||||
b_pixytest.base.x2=AUTO;
|
||||
b_pixytest.base.y2=AUTO;
|
||||
b_pixytest.txtcolor=BLACK;
|
||||
b_pixytest.bgcolor=HEX(0x00FA96);
|
||||
b_pixytest.font=0;
|
||||
b_pixytest.text="Pixy";
|
||||
b_pixytest.callback=b_pixytest_cb;
|
||||
gui_button_add(&b_pixytest);
|
||||
b_pixytest.base.x1 = b_guitest.base.x2 + BUTTON_SPACING;
|
||||
b_pixytest.base.y1 = Y_THIRD - 3;
|
||||
b_pixytest.base.x2 = AUTO;
|
||||
b_pixytest.base.y2 = AUTO;
|
||||
b_pixytest.txtcolor = BLACK;
|
||||
b_pixytest.bgcolor = HEX(0x00FA96);
|
||||
b_pixytest.font = 0;
|
||||
b_pixytest.text = "Pixy";
|
||||
b_pixytest.callback = b_pixytest_cb;
|
||||
gui_button_add(&b_pixytest);
|
||||
|
||||
|
||||
b_filetest.base.x1=b_pixytest.base.x2+BUTTON_SPACING;
|
||||
b_filetest.base.y1=Y_THIRD-3;
|
||||
b_filetest.base.x2=AUTO;
|
||||
b_filetest.base.y2=AUTO;
|
||||
b_filetest.txtcolor=BLACK;
|
||||
b_filetest.bgcolor=HEX(0x00FAC4);
|
||||
b_filetest.font=0;
|
||||
b_filetest.text="File";
|
||||
b_filetest.callback=b_filetest_cb;
|
||||
gui_button_add(&b_filetest);
|
||||
b_filetest.base.x1 = b_pixytest.base.x2 + BUTTON_SPACING;
|
||||
b_filetest.base.y1 = Y_THIRD - 3;
|
||||
b_filetest.base.x2 = AUTO;
|
||||
b_filetest.base.y2 = AUTO;
|
||||
b_filetest.txtcolor = BLACK;
|
||||
b_filetest.bgcolor = HEX(0x00FAC4);
|
||||
b_filetest.font = 0;
|
||||
b_filetest.text = "File";
|
||||
b_filetest.callback = b_filetest_cb;
|
||||
gui_button_add(&b_filetest);
|
||||
|
||||
|
||||
//Bottom line
|
||||
tft_draw_line(0,145,319,145,BLACK);
|
||||
tft_print_line(10,150,BLUE,TRANSPARENT,0,"Powered by");
|
||||
tft_draw_bitmap_file_unscaled(10,165,"pixy_small.bmp");
|
||||
tft_draw_bitmap_file_unscaled(165,165,"stm_small.bmp");
|
||||
//Bottom line
|
||||
tft_draw_line(0, 145, 319, 145, BLACK);
|
||||
tft_print_line(10, 150, BLUE, TRANSPARENT, 0, "Powered by");
|
||||
tft_draw_bitmap_file_unscaled(10, 165, "pixy_small.bmp");
|
||||
tft_draw_bitmap_file_unscaled(165, 165, "stm_small.bmp");
|
||||
|
||||
}
|
||||
|
||||
static void leave(void* screen) {
|
||||
gui_button_remove(&b_our_tracking);
|
||||
gui_button_remove(&b_ref_tracking);
|
||||
gui_button_remove(&b_photo_mode);
|
||||
gui_button_remove(&b_guitest);
|
||||
gui_button_remove(&b_pixytest);
|
||||
gui_button_remove(&b_filetest);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
gui_button_remove(&b_our_tracking);
|
||||
gui_button_remove(&b_ref_tracking);
|
||||
gui_button_remove(&b_photo_mode);
|
||||
gui_button_remove(&b_guitest);
|
||||
gui_button_remove(&b_pixytest);
|
||||
gui_button_remove(&b_filetest);
|
||||
}
|
||||
|
||||
static void update(void* screen) {
|
||||
//gui_button_redraw(&b_guitest); //only needed if button is overdrawn by others
|
||||
static void update(void* screen)
|
||||
{
|
||||
//gui_button_redraw(&b_guitest); //only needed if button is overdrawn by others
|
||||
}
|
||||
|
||||
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_main() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_main()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_main.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
|
||||
* 2015-05-12 timolang@gmail.com 1402598 Added doxygen stuff for button module and some minor changes to touch, screen_main and tft module.
|
||||
* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_photomode.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
|
||||
* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_photomode.h"
|
||||
#include "screen_photomode_save.h"
|
||||
#include "button.h"
|
||||
@@ -12,155 +27,182 @@ static bool pixy_connected = false; //Whether or not the pixy cam is currently c
|
||||
static BUTTON_STRUCT b_back; //Button to navigate back
|
||||
static BUTTON_STRUCT b_save; //Button to save the current image
|
||||
static TOUCH_AREA_STRUCT a_area; //Touch Area, where the frame is drawn. Used to drag the image around
|
||||
static bool subMenu=false; //Whether or not we left the current screen for a submenu
|
||||
static bool subMenu = false; //Whether or not we left the current screen for a submenu
|
||||
|
||||
//Callback for when the user presses the "back" button
|
||||
static void b_back_cb(void* button) {
|
||||
subMenu = false; //we're not entering a submenu
|
||||
gui_screen_back(); //navigate back to the previous screen
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
subMenu = false; //we're not entering a submenu
|
||||
gui_screen_back(); //navigate back to the previous screen
|
||||
}
|
||||
|
||||
//Callback for when the user presses the "save" button
|
||||
static void b_save_cb(void* button) {
|
||||
subMenu = true; //we're entering a submenu
|
||||
gui_screen_navigate(get_screen_photomodesave()); //navigate to the save screen
|
||||
static void b_save_cb(void* button)
|
||||
{
|
||||
subMenu = true; //we're entering a submenu
|
||||
gui_screen_navigate(get_screen_photomodesave()); //navigate to the save screen
|
||||
}
|
||||
|
||||
static POINT_STRUCT pixy_pos; //The current position of pixy's servos
|
||||
static POINT_STRUCT old_pos; //The last touch position on the screen
|
||||
|
||||
//Callback for when the user drags the image around
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
|
||||
POINT_STRUCT p = touch_get_last_point(); //get the last touched point
|
||||
switch(triggeredAction) {
|
||||
case PEN_ENTER:
|
||||
case PEN_DOWN:
|
||||
old_pos = p; //If the user "newly" enters the touch area, we set the "last" position to the current
|
||||
break;
|
||||
case PEN_MOVE: //the user is moving around, he entered the screen a while ago (old_pos is set)
|
||||
{
|
||||
int16_t deltaX = p.x - old_pos.x; //Calculate x difference between last and current touch
|
||||
int16_t deltaY = p.y - old_pos.y; //Calculate y difference between last and current touch
|
||||
old_pos=p; //store the current touch point for the next time
|
||||
//printf("%d %d\n",deltaX,deltaY);
|
||||
if(pixy_connected) {
|
||||
//Calculate new servo coordinates. 2 is just a proportional factor
|
||||
int16_t new_x = pixy_pos.x+deltaX*2;
|
||||
int16_t new_y = pixy_pos.y-deltaY*2;
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
|
||||
{
|
||||
POINT_STRUCT p = touch_get_last_point(); //get the last touched point
|
||||
|
||||
//check limits
|
||||
if(new_x<0) new_x=0;
|
||||
if(new_x>1000) new_x=1000;
|
||||
if(new_y<0) new_y=0;
|
||||
if(new_y>1000) new_y=1000;
|
||||
|
||||
//set pixy_pos so that the main routine can send it to the servos
|
||||
pixy_pos.x = new_x;
|
||||
pixy_pos.y= new_y;
|
||||
}
|
||||
}
|
||||
switch (triggeredAction) {
|
||||
case PEN_ENTER:
|
||||
case PEN_DOWN:
|
||||
old_pos = p; //If the user "newly" enters the touch area, we set the "last" position to the current
|
||||
break;
|
||||
case PEN_UP:
|
||||
case PEN_LEAVE:
|
||||
//printf("Leave/up\n");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
case PEN_MOVE: { //the user is moving around, he entered the screen a while ago (old_pos is set)
|
||||
int16_t deltaX = p.x - old_pos.x; //Calculate x difference between last and current touch
|
||||
int16_t deltaY = p.y - old_pos.y; //Calculate y difference between last and current touch
|
||||
old_pos = p; //store the current touch point for the next time
|
||||
|
||||
//printf("%d %d\n",deltaX,deltaY);
|
||||
if (pixy_connected) {
|
||||
//Calculate new servo coordinates. 2 is just a proportional factor
|
||||
int16_t new_x = pixy_pos.x + deltaX * 2;
|
||||
int16_t new_y = pixy_pos.y - deltaY * 2;
|
||||
|
||||
//check limits
|
||||
if (new_x < 0) {
|
||||
new_x = 0;
|
||||
}
|
||||
|
||||
if (new_x > 1000) {
|
||||
new_x = 1000;
|
||||
}
|
||||
|
||||
if (new_y < 0) {
|
||||
new_y = 0;
|
||||
}
|
||||
|
||||
if (new_y > 1000) {
|
||||
new_y = 1000;
|
||||
}
|
||||
|
||||
//set pixy_pos so that the main routine can send it to the servos
|
||||
pixy_pos.x = new_x;
|
||||
pixy_pos.y = new_y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PEN_UP:
|
||||
case PEN_LEAVE:
|
||||
//printf("Leave/up\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Callback for when the screen is entered/loaded
|
||||
static void enter(void* screen) {
|
||||
tft_clear(WHITE);
|
||||
|
||||
tft_print_line(5,5,BLACK,TRANSPARENT,0,"Drag the image around and ");
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(WHITE);
|
||||
|
||||
//Back button
|
||||
b_back.base.x1=5; //Start X of Button
|
||||
b_back.base.y1=19; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
tft_print_line(5, 5, BLACK, TRANSPARENT, 0, "Drag the image around and ");
|
||||
|
||||
//Save button
|
||||
b_save.base.x1=190;
|
||||
b_save.base.y1=3;
|
||||
b_save.base.x2=AUTO;
|
||||
b_save.base.y2=AUTO;
|
||||
b_save.txtcolor=WHITE;
|
||||
b_save.bgcolor=HEX(0x1010AE);
|
||||
b_save.font=0;
|
||||
b_save.text="Save it!";
|
||||
b_save.callback=b_save_cb;
|
||||
gui_button_add(&b_save);
|
||||
//Back button
|
||||
b_back.base.x1 = 5; //Start X of Button
|
||||
b_back.base.y1 = 19; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
//Frame Coordinates: topleft = (1,40); bottomright = (318,238)
|
||||
//Leave a 10px border for the area
|
||||
//Save button
|
||||
b_save.base.x1 = 190;
|
||||
b_save.base.y1 = 3;
|
||||
b_save.base.x2 = AUTO;
|
||||
b_save.base.y2 = AUTO;
|
||||
b_save.txtcolor = WHITE;
|
||||
b_save.bgcolor = HEX(0x1010AE);
|
||||
b_save.font = 0;
|
||||
b_save.text = "Save it!";
|
||||
b_save.callback = b_save_cb;
|
||||
gui_button_add(&b_save);
|
||||
|
||||
//Area to drag the image around
|
||||
a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE;
|
||||
a_area.x1 = 11;
|
||||
a_area.y1 = 50;
|
||||
a_area.x2 = 308;
|
||||
a_area.y2 = 228;
|
||||
a_area.callback = touchCB;
|
||||
touch_register_area(&a_area);
|
||||
//Frame Coordinates: topleft = (1,40); bottomright = (318,238)
|
||||
//Leave a 10px border for the area
|
||||
|
||||
//Pixy stuff
|
||||
pixy_connected = (pixy_init()==0); //try to connect to pixy
|
||||
if(pixy_connected && !subMenu) { //pixy is connected, but we are not coming from a submenu
|
||||
pixy_pos.x=pixy_pos.y=500; //reset servo positions to center
|
||||
}
|
||||
//Area to drag the image around
|
||||
a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE;
|
||||
a_area.x1 = 11;
|
||||
a_area.y1 = 50;
|
||||
a_area.x2 = 308;
|
||||
a_area.y2 = 228;
|
||||
a_area.callback = touchCB;
|
||||
touch_register_area(&a_area);
|
||||
|
||||
//Pixy stuff
|
||||
pixy_connected = (pixy_init() == 0); //try to connect to pixy
|
||||
|
||||
if (pixy_connected && !subMenu) { //pixy is connected, but we are not coming from a submenu
|
||||
pixy_pos.x = pixy_pos.y = 500; //reset servo positions to center
|
||||
}
|
||||
}
|
||||
|
||||
//Callback for when the screen is left/unloaded
|
||||
static void leave(void* screen) {
|
||||
//remove buttons and touch area.
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_save);
|
||||
touch_unregister_area(&a_area);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
//remove buttons and touch area.
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_save);
|
||||
touch_unregister_area(&a_area);
|
||||
}
|
||||
|
||||
//Callback for when the screen should be updated
|
||||
//This is the main loop of the screen. This method will be called repeatedly
|
||||
static void update(void* screen) {
|
||||
//Note: The only way to detect that pixy has been disconnected is if a command fails. There's no pixy_is_connected method yet :'(
|
||||
static void update(void* screen)
|
||||
{
|
||||
//Note: The only way to detect that pixy has been disconnected is if a command fails. There's no pixy_is_connected method yet :'(
|
||||
|
||||
if(!pixy_connected) { //Pixy not connected
|
||||
pixy_close(); //Ensure that all pixy resources are freed (failsafe)
|
||||
if(pixy_init()==0) { //try to connect to pixy
|
||||
pixy_connected=true;
|
||||
if(!subMenu) { //we're not coming from a submenu
|
||||
pixy_pos.x=pixy_pos.y=500; //reset servo positions to center
|
||||
}
|
||||
printf("pixy (re)initialized\n");
|
||||
}
|
||||
}
|
||||
if (!pixy_connected) { //Pixy not connected
|
||||
pixy_close(); //Ensure that all pixy resources are freed (failsafe)
|
||||
|
||||
if(pixy_connected) { //If we are connected (now)
|
||||
pixy_service(); //Handle pending pixy events (e.g. color info retrival)
|
||||
if (pixy_init() == 0) { //try to connect to pixy
|
||||
pixy_connected = true;
|
||||
|
||||
pixy_render_full_frame(1,40); //render the pixy video at point (1,40)
|
||||
|
||||
//set the servo positions to the coordinates form the touch interrupt
|
||||
pixy_rcs_set_position(0,pixy_pos.x);
|
||||
pixy_rcs_set_position(1,pixy_pos.y);
|
||||
}
|
||||
if (!subMenu) { //we're not coming from a submenu
|
||||
pixy_pos.x = pixy_pos.y = 500; //reset servo positions to center
|
||||
}
|
||||
|
||||
printf("pixy (re)initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (pixy_connected) { //If we are connected (now)
|
||||
pixy_service(); //Handle pending pixy events (e.g. color info retrival)
|
||||
|
||||
pixy_render_full_frame(1, 40); //render the pixy video at point (1,40)
|
||||
|
||||
//set the servo positions to the coordinates form the touch interrupt
|
||||
pixy_rcs_set_position(0, pixy_pos.x);
|
||||
pixy_rcs_set_position(1, pixy_pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
//Declare screen callbacks
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_photomode() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_photomode()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_photomode.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_photomode_save.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_photomode_save.h"
|
||||
#include "filesystem.h"
|
||||
#include "button.h"
|
||||
@@ -13,8 +27,9 @@ static BUTTON_STRUCT b_back; //Button to navigate back
|
||||
static TOUCH_AREA_STRUCT a_area; //Touch area to select the save-file
|
||||
|
||||
//Callback for when the user presses the "back" button
|
||||
static void b_back_cb(void* button) {
|
||||
gui_screen_back();
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
gui_screen_back();
|
||||
}
|
||||
|
||||
static int num_files_ok; //number of files into which we can write the image (size, flags ok)
|
||||
@@ -24,46 +39,51 @@ static int liststart; //The y-Coordinate of the Start of the File-List
|
||||
static const char* picked_file; //The filename picked by the user, to save the image to
|
||||
|
||||
//Linked list structure to save all files which are suitable for saving.
|
||||
typedef struct FILE_LIST_ENTRY_S{
|
||||
char* filename; //Name of the file
|
||||
struct FILE_LIST_ENTRY_S* next; //Pointer to the next entry in the list or NULL
|
||||
typedef struct FILE_LIST_ENTRY_S {
|
||||
char* filename; //Name of the file
|
||||
struct FILE_LIST_ENTRY_S* next; //Pointer to the next entry in the list or NULL
|
||||
} FILE_LIST_ENTRY;
|
||||
|
||||
static FILE_LIST_ENTRY* files_ok; //Pointer to the head of the list
|
||||
|
||||
//Callback for when the user selects a file to save the image into
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
|
||||
{
|
||||
|
||||
int y = touch_get_last_point().y-liststart; //Calculate the y-Coordinate of the touch point relative to the start of the file-list
|
||||
int elem = y/fontheight; //Calculate the file index
|
||||
if(elem<0 | elem>= num_files_ok) return; //Check if the file index is valid (0,1,..,num_files_ok-1)
|
||||
int y = touch_get_last_point().y - liststart; //Calculate the y-Coordinate of the touch point relative to the start of the file-list
|
||||
int elem = y / fontheight; //Calculate the file index
|
||||
|
||||
//Search for the corresponding entry in the linked list
|
||||
FILE_LIST_ENTRY* current_entry = files_ok; //Start walking through the list, starting by the head of the list
|
||||
for(int i=0; i<elem; i++) { //Until we have reached the file (index)
|
||||
current_entry= current_entry->next; //traverse to the next file
|
||||
}
|
||||
if (elem < 0 | elem >= num_files_ok) {
|
||||
return; //Check if the file index is valid (0,1,..,num_files_ok-1)
|
||||
}
|
||||
|
||||
picked_file = current_entry->filename; //save the picked filename. It will be used by the statemachine in the main loop
|
||||
touch_unregister_area(&a_area); //unregister the touch area, we no longer need it. No more interrupts will be fired.
|
||||
state=saving; //Change the state of the statemachine
|
||||
//Search for the corresponding entry in the linked list
|
||||
FILE_LIST_ENTRY* current_entry = files_ok; //Start walking through the list, starting by the head of the list
|
||||
|
||||
for (int i = 0; i < elem; i++) { //Until we have reached the file (index)
|
||||
current_entry = current_entry->next; //traverse to the next file
|
||||
}
|
||||
|
||||
picked_file = current_entry->filename; //save the picked filename. It will be used by the statemachine in the main loop
|
||||
touch_unregister_area(&a_area); //unregister the touch area, we no longer need it. No more interrupts will be fired.
|
||||
state = saving; //Change the state of the statemachine
|
||||
}
|
||||
|
||||
//Text-Lines to show if we have no matching files (num_files_ok==0)
|
||||
static const char* nomatch_text [] = {
|
||||
"Due to limitations of the filesystem",
|
||||
"implementation you can only write to",
|
||||
"existing files.",
|
||||
"",
|
||||
"The files need to have a .bmp",
|
||||
"extension and must be at least",
|
||||
"189410 bytes (185kb) large.",
|
||||
"Unfortunately there were no such",
|
||||
"files found in the root directory.",
|
||||
"",
|
||||
"Please create some files and come",
|
||||
"back again.",
|
||||
NULL
|
||||
"Due to limitations of the filesystem",
|
||||
"implementation you can only write to",
|
||||
"existing files.",
|
||||
"",
|
||||
"The files need to have a .bmp",
|
||||
"extension and must be at least",
|
||||
"189410 bytes (185kb) large.",
|
||||
"Unfortunately there were no such",
|
||||
"files found in the root directory.",
|
||||
"",
|
||||
"Please create some files and come",
|
||||
"back again.",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -71,231 +91,251 @@ static const char* nomatch_text [] = {
|
||||
//This header has been taken from a white bitmap saved with gimp.
|
||||
//Wikipedia has a pretty good description on the header: http://de.wikipedia.org/wiki/Windows_Bitmap
|
||||
static unsigned char bmpheader_data[0x7A] = {
|
||||
0x42, 0x4d, 0xe2, 0xe3, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0xc6, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe3,
|
||||
0x02, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
0x42, 0x4d, 0xe2, 0xe3, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0xc6, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe3,
|
||||
0x02, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
};
|
||||
|
||||
//Callback for when the screen is entered/loaded
|
||||
static void enter(void* screen) {
|
||||
tft_clear(WHITE);
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(WHITE);
|
||||
|
||||
|
||||
#define X_OFS 5
|
||||
#define X_OFS 5
|
||||
|
||||
//Back button
|
||||
b_back.base.x1=X_OFS; //Start X of Button
|
||||
b_back.base.y1=210; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
//Back button
|
||||
b_back.base.x1 = X_OFS; //Start X of Button
|
||||
b_back.base.y1 = 210; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
state =init; //Start with the init state
|
||||
fontheight = tft_font_height(0)+2; //Save the height of the used font, for fast access
|
||||
files_ok = NULL; //initialize the linked list with 0 elements
|
||||
num_files_ok = 0; //we have zero! elements
|
||||
state = init; //Start with the init state
|
||||
fontheight = tft_font_height(0) + 2; //Save the height of the used font, for fast access
|
||||
files_ok = NULL; //initialize the linked list with 0 elements
|
||||
num_files_ok = 0; //we have zero! elements
|
||||
}
|
||||
|
||||
//Callback for when the screen should be updated
|
||||
//This is the main loop of the screen. This method will be called repeatedly
|
||||
static void update(void* screen) {
|
||||
switch(state) {
|
||||
case init: //Init State: The user just entered the screen
|
||||
{
|
||||
DIRECTORY_STRUCT* dir = filesystem_dir_open("."); //open root directory
|
||||
if(dir==NULL) { //error while opening root directory
|
||||
tft_print_line(X_OFS,5,BLACK,TRANSPARENT,0,"Error accessing Filesystem");
|
||||
state=error;
|
||||
break;
|
||||
}
|
||||
static void update(void* screen)
|
||||
{
|
||||
switch (state) {
|
||||
case init: { //Init State: The user just entered the screen
|
||||
DIRECTORY_STRUCT* dir = filesystem_dir_open("."); //open root directory
|
||||
|
||||
bool nomatch= true; //whether or not we have zero files which are suitable for saving
|
||||
if (dir == NULL) { //error while opening root directory
|
||||
tft_print_line(X_OFS, 5, BLACK, TRANSPARENT, 0, "Error accessing Filesystem");
|
||||
state = error;
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i=0; i<dir->num_files; i++) { //walk through all files in the directory
|
||||
FILE_STRUCT* file = &(dir->files[i]); //Pointer to the current file/subdirectory
|
||||
bool nomatch = true; //whether or not we have zero files which are suitable for saving
|
||||
|
||||
//Ignore directories, archives, hidden files, system files and files we cannot write to
|
||||
if(file->fattrib&(F_SYS|F_HID|F_ARC|F_DIR|F_RDO)) continue;
|
||||
for (int i = 0; i < dir->num_files; i++) { //walk through all files in the directory
|
||||
FILE_STRUCT* file = &(dir->files[i]); //Pointer to the current file/subdirectory
|
||||
|
||||
//ignore files which are not large enough
|
||||
if(file->fsize<189410) continue; //size taken from an example bitmap (318x198x24)
|
||||
//Ignore directories, archives, hidden files, system files and files we cannot write to
|
||||
if (file->fattrib & (F_SYS | F_HID | F_ARC | F_DIR | F_RDO)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nomatch=false; //at least one file matches
|
||||
break;
|
||||
}
|
||||
//ignore files which are not large enough
|
||||
if (file->fsize < 189410) {
|
||||
continue; //size taken from an example bitmap (318x198x24)
|
||||
}
|
||||
|
||||
if(nomatch) { //not one file is suitable for writing
|
||||
int y=5; //y-Coordinate where to start writing the error text
|
||||
int i=0;
|
||||
while(nomatch_text[i]!=NULL) { //for every line in the big error array
|
||||
//Write the line's text and go to the next line
|
||||
tft_print_line(X_OFS,y+i*fontheight,BLACK,TRANSPARENT,0,nomatch_text[i]);
|
||||
i++;
|
||||
}
|
||||
state = error;
|
||||
} else { //we have a least one suitable file
|
||||
state = showlist;
|
||||
}
|
||||
nomatch = false; //at least one file matches
|
||||
break;
|
||||
}
|
||||
|
||||
filesystem_dir_close(dir); //free directory struct
|
||||
}
|
||||
break;
|
||||
if (nomatch) { //not one file is suitable for writing
|
||||
int y = 5; //y-Coordinate where to start writing the error text
|
||||
int i = 0;
|
||||
|
||||
case showlist: //Show List State: Where we load and present the suitable file's to the user in a list
|
||||
{
|
||||
DIRECTORY_STRUCT* dir2 = filesystem_dir_open("."); //Open the directory again
|
||||
if(dir2==NULL) return; //Error on opening? This should never happen, since it's handled in the previous state
|
||||
while (nomatch_text[i] != NULL) { //for every line in the big error array
|
||||
//Write the line's text and go to the next line
|
||||
tft_print_line(X_OFS, y + i * fontheight, BLACK, TRANSPARENT, 0, nomatch_text[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
int y = 5; //y-Coordinate where to start drawing/writing text/list-elements
|
||||
state = error;
|
||||
} else { //we have a least one suitable file
|
||||
state = showlist;
|
||||
}
|
||||
|
||||
tft_print_line(X_OFS,y,BLACK,TRANSPARENT,0,"Pick a file to save the image to");
|
||||
y+=fontheight+5;
|
||||
filesystem_dir_close(dir); //free directory struct
|
||||
}
|
||||
break;
|
||||
|
||||
tft_print_line(X_OFS,y,BLUE,TRANSPARENT,0,"Name Modified Size");
|
||||
y+=fontheight;
|
||||
case showlist: { //Show List State: Where we load and present the suitable file's to the user in a list
|
||||
DIRECTORY_STRUCT* dir2 = filesystem_dir_open("."); //Open the directory again
|
||||
|
||||
liststart = y; //store the y coordinate of the start of the list away (used in toucharea callback)
|
||||
num_files_ok = 0; //we start with 0 matching files
|
||||
if (dir2 == NULL) {
|
||||
return; //Error on opening? This should never happen, since it's handled in the previous state
|
||||
}
|
||||
|
||||
FILE_LIST_ENTRY* current_entry = NULL; //We start with an empty list
|
||||
for(int i=0; i<dir2->num_files && num_files_ok<10; i++) { //go through all the files of the directory, abort if we have 10 matches
|
||||
FILE_STRUCT* file = &(dir2->files[i]);
|
||||
int y = 5; //y-Coordinate where to start drawing/writing text/list-elements
|
||||
|
||||
//Ignore directories, archives, hidden files, system files and files we cannot write to
|
||||
if(file->fattrib&(F_SYS|F_HID|F_ARC|F_DIR|F_RDO)) continue;
|
||||
tft_print_line(X_OFS, y, BLACK, TRANSPARENT, 0, "Pick a file to save the image to");
|
||||
y += fontheight + 5;
|
||||
|
||||
//ignore files which are not large enough
|
||||
if(file->fsize<189410) continue; //size taken from an example bitmap (318x198x24)
|
||||
tft_print_line(X_OFS, y, BLUE, TRANSPARENT, 0, "Name Modified Size");
|
||||
y += fontheight;
|
||||
|
||||
//Print out filename, modified date,time and file size
|
||||
tft_print_formatted(X_OFS,y,BLACK,
|
||||
TRANSPARENT,0,"%-16s %02u.%02u.%02u %02u:%02u:%02u %u",
|
||||
file->fname,
|
||||
file->fdate.day,
|
||||
file->fdate.month,
|
||||
(file->fdate.year+1980)%100,
|
||||
file->ftime.hour,
|
||||
file->ftime.min,
|
||||
file->ftime.sec*2,
|
||||
file->fsize);
|
||||
liststart = y; //store the y coordinate of the start of the list away (used in toucharea callback)
|
||||
num_files_ok = 0; //we start with 0 matching files
|
||||
|
||||
if(current_entry==NULL) { //The list is empty
|
||||
current_entry = malloc(sizeof(FILE_LIST_ENTRY)); //create new entry
|
||||
files_ok = current_entry; //assign it to the list head
|
||||
} else { //there's a least one entry in the list
|
||||
current_entry->next = malloc(sizeof(FILE_LIST_ENTRY)); //append entry to previous entry
|
||||
current_entry = current_entry->next; //newly created entry is the current now.
|
||||
}
|
||||
current_entry->next = NULL; //we're at the end of the list (for now)
|
||||
current_entry->filename = malloc(strlen(file->fname)+1); //allocate space for the filename + zero-termination
|
||||
strcpy(current_entry->filename,file->fname); //copy filename (so that we can close the directory after scanning)
|
||||
FILE_LIST_ENTRY* current_entry = NULL; //We start with an empty list
|
||||
|
||||
//since we have found a suitable file we need to increment the position in the list
|
||||
num_files_ok++;
|
||||
y+=fontheight;
|
||||
}
|
||||
for (int i = 0; i < dir2->num_files && num_files_ok < 10; i++) { //go through all the files of the directory, abort if we have 10 matches
|
||||
FILE_STRUCT* file = &(dir2->files[i]);
|
||||
|
||||
//Touch area for file-selection (in the list)
|
||||
a_area.hookedActions = PEN_UP; //we're only interested in PEN_UP events
|
||||
a_area.x1 = X_OFS; //Left border
|
||||
a_area.y1 = liststart; //Start where the list started
|
||||
a_area.x2 = 320-X_OFS; //Right border
|
||||
a_area.y2 = liststart+fontheight*num_files_ok; //stop at the end of the list
|
||||
a_area.callback = touchCB; //execute our callback when PEN_UP occurs
|
||||
touch_register_area(&a_area); //register the touch area and receive events from now on
|
||||
//Ignore directories, archives, hidden files, system files and files we cannot write to
|
||||
if (file->fattrib & (F_SYS | F_HID | F_ARC | F_DIR | F_RDO)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
filesystem_dir_close(dir2); //we no longer need the directory struct, since we have our own linked list now
|
||||
//ignore files which are not large enough
|
||||
if (file->fsize < 189410) {
|
||||
continue; //size taken from an example bitmap (318x198x24)
|
||||
}
|
||||
|
||||
state=picking;
|
||||
}
|
||||
break;
|
||||
//Print out filename, modified date,time and file size
|
||||
tft_print_formatted(X_OFS, y, BLACK,
|
||||
TRANSPARENT, 0, "%-16s %02u.%02u.%02u %02u:%02u:%02u %u",
|
||||
file->fname,
|
||||
file->fdate.day,
|
||||
file->fdate.month,
|
||||
(file->fdate.year + 1980) % 100,
|
||||
file->ftime.hour,
|
||||
file->ftime.min,
|
||||
file->ftime.sec * 2,
|
||||
file->fsize);
|
||||
|
||||
case picking: //Picking State: Where we wait on the users file choice
|
||||
pixy_service(); //Handle pending pixy events
|
||||
//do nothing and wait on user to pick a file
|
||||
break;
|
||||
if (current_entry == NULL) { //The list is empty
|
||||
current_entry = malloc(sizeof(FILE_LIST_ENTRY)); //create new entry
|
||||
files_ok = current_entry; //assign it to the list head
|
||||
} else { //there's a least one entry in the list
|
||||
current_entry->next = malloc(sizeof(FILE_LIST_ENTRY)); //append entry to previous entry
|
||||
current_entry = current_entry->next; //newly created entry is the current now.
|
||||
}
|
||||
|
||||
case saving: //Saving State: Where we save the image to the selected file
|
||||
{
|
||||
FILE_HANDLE* file = filesystem_file_open(picked_file); //try to open the selected file
|
||||
if(file==NULL) { //opening the file failed
|
||||
tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Could not open %s",picked_file);
|
||||
state=error;
|
||||
break;
|
||||
}
|
||||
current_entry->next = NULL; //we're at the end of the list (for now)
|
||||
current_entry->filename = malloc(strlen(file->fname) + 1); //allocate space for the filename + zero-termination
|
||||
strcpy(current_entry->filename, file->fname); //copy filename (so that we can close the directory after scanning)
|
||||
|
||||
filesystem_file_seek(file,0); //seek to the start of the file (optional?)
|
||||
if(filesystem_file_write(file,bmpheader_data,0x7A)!=F_OK) { //Writing the header failed
|
||||
tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Error while writing to %s",picked_file);
|
||||
filesystem_file_close(file);
|
||||
state=error;
|
||||
break;
|
||||
}
|
||||
//since we have found a suitable file we need to increment the position in the list
|
||||
num_files_ok++;
|
||||
y += fontheight;
|
||||
}
|
||||
|
||||
if(pixy_save_full_frame(file)!=0) { //Writing the imagedata failed
|
||||
tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Error while writing to %s",picked_file);
|
||||
filesystem_file_close(file);
|
||||
state=error;
|
||||
break;
|
||||
}
|
||||
//Touch area for file-selection (in the list)
|
||||
a_area.hookedActions = PEN_UP; //we're only interested in PEN_UP events
|
||||
a_area.x1 = X_OFS; //Left border
|
||||
a_area.y1 = liststart; //Start where the list started
|
||||
a_area.x2 = 320 - X_OFS; //Right border
|
||||
a_area.y2 = liststart + fontheight * num_files_ok; //stop at the end of the list
|
||||
a_area.callback = touchCB; //execute our callback when PEN_UP occurs
|
||||
touch_register_area(&a_area); //register the touch area and receive events from now on
|
||||
|
||||
//if we reach this point, we have written all data out successfully
|
||||
filesystem_dir_close(dir2); //we no longer need the directory struct, since we have our own linked list now
|
||||
|
||||
filesystem_file_close(file); //close/finalize the file
|
||||
tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Image saved to %s",picked_file);
|
||||
state = done;
|
||||
}
|
||||
break;
|
||||
state = picking;
|
||||
}
|
||||
break;
|
||||
|
||||
case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
|
||||
case done: //Done State: When saving the file was successful
|
||||
pixy_service(); //Handle pending pixy events
|
||||
//wait on user to click the back button
|
||||
break;
|
||||
case picking: //Picking State: Where we wait on the users file choice
|
||||
pixy_service(); //Handle pending pixy events
|
||||
//do nothing and wait on user to pick a file
|
||||
break;
|
||||
|
||||
}
|
||||
case saving: { //Saving State: Where we save the image to the selected file
|
||||
FILE_HANDLE* file = filesystem_file_open(picked_file); //try to open the selected file
|
||||
|
||||
if (file == NULL) { //opening the file failed
|
||||
tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Could not open %s", picked_file);
|
||||
state = error;
|
||||
break;
|
||||
}
|
||||
|
||||
filesystem_file_seek(file, 0); //seek to the start of the file (optional?)
|
||||
|
||||
if (filesystem_file_write(file, bmpheader_data, 0x7A) != F_OK) { //Writing the header failed
|
||||
tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Error while writing to %s", picked_file);
|
||||
filesystem_file_close(file);
|
||||
state = error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pixy_save_full_frame(file) != 0) { //Writing the imagedata failed
|
||||
tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Error while writing to %s", picked_file);
|
||||
filesystem_file_close(file);
|
||||
state = error;
|
||||
break;
|
||||
}
|
||||
|
||||
//if we reach this point, we have written all data out successfully
|
||||
|
||||
filesystem_file_close(file); //close/finalize the file
|
||||
tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Image saved to %s", picked_file);
|
||||
state = done;
|
||||
}
|
||||
break;
|
||||
|
||||
case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
|
||||
case done: //Done State: When saving the file was successful
|
||||
pixy_service(); //Handle pending pixy events
|
||||
//wait on user to click the back button
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Callback for when the screen is left/unloaded
|
||||
static void leave(void* screen) {
|
||||
gui_button_remove(&b_back); //Remove/Free the back button
|
||||
static void leave(void* screen)
|
||||
{
|
||||
gui_button_remove(&b_back); //Remove/Free the back button
|
||||
|
||||
if(state==picking){ //The user left the screen in the "picking"-phase
|
||||
touch_unregister_area(&a_area); //remove the touch area (for the list)
|
||||
}
|
||||
if (state == picking) { //The user left the screen in the "picking"-phase
|
||||
touch_unregister_area(&a_area); //remove the touch area (for the list)
|
||||
}
|
||||
|
||||
if(state==picking|| state==saving || state==done) { //the user left the screen after we created the linked list
|
||||
//Iterate through the linked list and free all resources
|
||||
FILE_LIST_ENTRY* current_entry = files_ok; //start with the list head
|
||||
while(current_entry!=NULL) { //while we're not at the end
|
||||
FILE_LIST_ENTRY* temp = current_entry->next; //save the next pointer because we free the current element on the next line
|
||||
free((void*)(current_entry->filename)); //free filename
|
||||
free(current_entry); //free element itself
|
||||
current_entry= temp; //advance
|
||||
}
|
||||
}
|
||||
if (state == picking || state == saving || state == done) { //the user left the screen after we created the linked list
|
||||
//Iterate through the linked list and free all resources
|
||||
FILE_LIST_ENTRY* current_entry = files_ok; //start with the list head
|
||||
|
||||
while (current_entry != NULL) { //while we're not at the end
|
||||
FILE_LIST_ENTRY* temp = current_entry->next; //save the next pointer because we free the current element on the next line
|
||||
free((void*)(current_entry->filename)); //free filename
|
||||
free(current_entry); //free element itself
|
||||
current_entry = temp; //advance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Declare screen callbacks
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
SCREEN_STRUCT* get_screen_photomodesave() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_photomodesave()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_photomode_save.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
@@ -20,4 +33,3 @@ SCREEN_STRUCT* get_screen_photomodesave();
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_pixytest.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-02 timolang@gmail.com 3281616 Added some more touch functions. Improved pixy test. Drag the Image around!
|
||||
* 2015-05-09 timolang@gmail.com 0b5173e Added reference tracking.
|
||||
* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
|
||||
* 2015-05-25 timolang@gmail.com 6a61769 Reimplemented pixytest screen. Added a lot of Test-Buttons.
|
||||
* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
|
||||
* 2015-06-03 timolang@gmail.com 74aa186 Made pixy_test screen working again. Had to disable pixy_service. Recalibrated initial touch values.
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_pixytest.h"
|
||||
#include "button.h"
|
||||
#include "numupdown.h"
|
||||
@@ -7,7 +27,7 @@
|
||||
#include "system.h"
|
||||
#include "pixy_frame.h"
|
||||
|
||||
static volatile enum {detecting, idle,update_servos, update_ledcolor, update_ledcurrent} state; //Current state of the screen state machine
|
||||
static volatile enum {detecting, idle, update_servos, update_ledcolor, update_ledcurrent} state; //Current state of the screen state machine
|
||||
|
||||
static BUTTON_STRUCT b_back;
|
||||
|
||||
@@ -30,313 +50,328 @@ static uint32_t led_maxcurrent;
|
||||
static NUMUPDOWN_STRUCT n_led_powerlimit;
|
||||
|
||||
|
||||
static void b_back_cb(void* button) {
|
||||
gui_screen_back();
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
gui_screen_back();
|
||||
}
|
||||
|
||||
static void b_servos_center_cb(void* button) {
|
||||
if(state==idle) {
|
||||
servo_x=500;
|
||||
servo_y=500;
|
||||
state=update_servos;
|
||||
}
|
||||
static void b_servos_center_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
servo_x = 500;
|
||||
servo_y = 500;
|
||||
state = update_servos;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_servos_topleft_cb(void* button) {
|
||||
if(state==idle) {
|
||||
servo_x=0;
|
||||
servo_y=0;
|
||||
state=update_servos;
|
||||
}
|
||||
static void b_servos_topleft_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
servo_x = 0;
|
||||
servo_y = 0;
|
||||
state = update_servos;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_servos_topright_cb(void* button) {
|
||||
if(state==idle) {
|
||||
servo_x=1000;
|
||||
servo_y=0;
|
||||
state=update_servos;
|
||||
}
|
||||
static void b_servos_topright_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
servo_x = 1000;
|
||||
servo_y = 0;
|
||||
state = update_servos;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_servos_bottomleft_cb(void* button) {
|
||||
if(state==idle) {
|
||||
servo_x=0;
|
||||
servo_y=1000;
|
||||
state=update_servos;
|
||||
}
|
||||
static void b_servos_bottomleft_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
servo_x = 0;
|
||||
servo_y = 1000;
|
||||
state = update_servos;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_servos_bottomright_cb(void* button) {
|
||||
if(state==idle) {
|
||||
servo_x=1000;
|
||||
servo_y=1000;
|
||||
state=update_servos;
|
||||
}
|
||||
static void b_servos_bottomright_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
servo_x = 1000;
|
||||
servo_y = 1000;
|
||||
state = update_servos;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_led_off_cb(void* button) {
|
||||
if(state==idle) {
|
||||
led_color=0x000000;
|
||||
state=update_ledcolor;
|
||||
}
|
||||
static void b_led_off_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_color = 0x000000;
|
||||
state = update_ledcolor;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_led_white_cb(void* button) {
|
||||
if(state==idle) {
|
||||
led_color=0xFFFFFF;
|
||||
state=update_ledcolor;
|
||||
}
|
||||
static void b_led_white_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_color = 0xFFFFFF;
|
||||
state = update_ledcolor;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_led_red_cb(void* button) {
|
||||
if(state==idle) {
|
||||
led_color=0xFF0000;
|
||||
state=update_ledcolor;
|
||||
}
|
||||
static void b_led_red_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_color = 0xFF0000;
|
||||
state = update_ledcolor;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_led_green_cb(void* button) {
|
||||
if(state==idle) {
|
||||
led_color=0x00FF00;
|
||||
state=update_ledcolor;
|
||||
}
|
||||
static void b_led_green_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_color = 0x00FF00;
|
||||
state = update_ledcolor;
|
||||
}
|
||||
}
|
||||
|
||||
static void b_led_blue_cb(void* button) {
|
||||
if(state==idle) {
|
||||
led_color=0x0000FF;
|
||||
state=update_ledcolor;
|
||||
}
|
||||
static void b_led_blue_cb(void* button)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_color = 0x0000FF;
|
||||
state = update_ledcolor;
|
||||
}
|
||||
}
|
||||
|
||||
static void n_led_powerlimit_cb(void* numupdown, int16_t value) {
|
||||
if(state==idle) {
|
||||
led_maxcurrent=value;
|
||||
state=update_ledcurrent;
|
||||
}
|
||||
static void n_led_powerlimit_cb(void* numupdown, int16_t value)
|
||||
{
|
||||
if (state == idle) {
|
||||
led_maxcurrent = value;
|
||||
state = update_ledcurrent;
|
||||
}
|
||||
}
|
||||
|
||||
static void enter(void* screen) {
|
||||
tft_clear(WHITE);
|
||||
|
||||
//Back button
|
||||
b_back.base.x1=10; //Start X of Button
|
||||
b_back.base.y1=210; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(WHITE);
|
||||
|
||||
//Back button
|
||||
b_back.base.x1 = 10; //Start X of Button
|
||||
b_back.base.y1 = 210; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
|
||||
//Servo stuff
|
||||
#define SERVO_BUTTON_Y 10
|
||||
#define SERVO_BUTTON_SPACING 5
|
||||
tft_print_line(5,SERVO_BUTTON_Y,BLACK,TRANSPARENT,0,"Servos:");
|
||||
//Servo stuff
|
||||
#define SERVO_BUTTON_Y 10
|
||||
#define SERVO_BUTTON_SPACING 5
|
||||
tft_print_line(5, SERVO_BUTTON_Y, BLACK, TRANSPARENT, 0, "Servos:");
|
||||
|
||||
b_servos_center.base.x1=55;
|
||||
b_servos_center.base.y1=SERVO_BUTTON_Y-3;
|
||||
b_servos_center.base.x2=AUTO;
|
||||
b_servos_center.base.y2=AUTO;
|
||||
b_servos_center.txtcolor=WHITE;
|
||||
b_servos_center.bgcolor=HEX(0xAE1010);
|
||||
b_servos_center.font=0;
|
||||
b_servos_center.text="Center";
|
||||
b_servos_center.callback=b_servos_center_cb;
|
||||
gui_button_add(&b_servos_center);
|
||||
b_servos_center.base.x1 = 55;
|
||||
b_servos_center.base.y1 = SERVO_BUTTON_Y - 3;
|
||||
b_servos_center.base.x2 = AUTO;
|
||||
b_servos_center.base.y2 = AUTO;
|
||||
b_servos_center.txtcolor = WHITE;
|
||||
b_servos_center.bgcolor = HEX(0xAE1010);
|
||||
b_servos_center.font = 0;
|
||||
b_servos_center.text = "Center";
|
||||
b_servos_center.callback = b_servos_center_cb;
|
||||
gui_button_add(&b_servos_center);
|
||||
|
||||
b_servos_topleft.base.x1=b_servos_center.base.x2+SERVO_BUTTON_SPACING;
|
||||
b_servos_topleft.base.y1=SERVO_BUTTON_Y-3;
|
||||
b_servos_topleft.base.x2=AUTO;
|
||||
b_servos_topleft.base.y2=AUTO;
|
||||
b_servos_topleft.txtcolor=WHITE;
|
||||
b_servos_topleft.bgcolor=HEX(0xAE1010);
|
||||
b_servos_topleft.font=0;
|
||||
b_servos_topleft.text="ToLe";
|
||||
b_servos_topleft.callback=b_servos_topleft_cb;
|
||||
gui_button_add(&b_servos_topleft);
|
||||
b_servos_topleft.base.x1 = b_servos_center.base.x2 + SERVO_BUTTON_SPACING;
|
||||
b_servos_topleft.base.y1 = SERVO_BUTTON_Y - 3;
|
||||
b_servos_topleft.base.x2 = AUTO;
|
||||
b_servos_topleft.base.y2 = AUTO;
|
||||
b_servos_topleft.txtcolor = WHITE;
|
||||
b_servos_topleft.bgcolor = HEX(0xAE1010);
|
||||
b_servos_topleft.font = 0;
|
||||
b_servos_topleft.text = "ToLe";
|
||||
b_servos_topleft.callback = b_servos_topleft_cb;
|
||||
gui_button_add(&b_servos_topleft);
|
||||
|
||||
b_servos_topright.base.x1=b_servos_topleft.base.x2+SERVO_BUTTON_SPACING;
|
||||
b_servos_topright.base.y1=SERVO_BUTTON_Y-3;
|
||||
b_servos_topright.base.x2=AUTO;
|
||||
b_servos_topright.base.y2=AUTO;
|
||||
b_servos_topright.txtcolor=WHITE;
|
||||
b_servos_topright.bgcolor=HEX(0xAE1010);
|
||||
b_servos_topright.font=0;
|
||||
b_servos_topright.text="ToRi";
|
||||
b_servos_topright.callback=b_servos_topright_cb;
|
||||
gui_button_add(&b_servos_topright);
|
||||
b_servos_topright.base.x1 = b_servos_topleft.base.x2 + SERVO_BUTTON_SPACING;
|
||||
b_servos_topright.base.y1 = SERVO_BUTTON_Y - 3;
|
||||
b_servos_topright.base.x2 = AUTO;
|
||||
b_servos_topright.base.y2 = AUTO;
|
||||
b_servos_topright.txtcolor = WHITE;
|
||||
b_servos_topright.bgcolor = HEX(0xAE1010);
|
||||
b_servos_topright.font = 0;
|
||||
b_servos_topright.text = "ToRi";
|
||||
b_servos_topright.callback = b_servos_topright_cb;
|
||||
gui_button_add(&b_servos_topright);
|
||||
|
||||
b_servos_bottomleft.base.x1=b_servos_topright.base.x2+SERVO_BUTTON_SPACING;
|
||||
b_servos_bottomleft.base.y1=SERVO_BUTTON_Y-3;
|
||||
b_servos_bottomleft.base.x2=AUTO;
|
||||
b_servos_bottomleft.base.y2=AUTO;
|
||||
b_servos_bottomleft.txtcolor=WHITE;
|
||||
b_servos_bottomleft.bgcolor=HEX(0xAE1010);
|
||||
b_servos_bottomleft.font=0;
|
||||
b_servos_bottomleft.text="BoLe";
|
||||
b_servos_bottomleft.callback=b_servos_bottomleft_cb;
|
||||
gui_button_add(&b_servos_bottomleft);
|
||||
b_servos_bottomleft.base.x1 = b_servos_topright.base.x2 + SERVO_BUTTON_SPACING;
|
||||
b_servos_bottomleft.base.y1 = SERVO_BUTTON_Y - 3;
|
||||
b_servos_bottomleft.base.x2 = AUTO;
|
||||
b_servos_bottomleft.base.y2 = AUTO;
|
||||
b_servos_bottomleft.txtcolor = WHITE;
|
||||
b_servos_bottomleft.bgcolor = HEX(0xAE1010);
|
||||
b_servos_bottomleft.font = 0;
|
||||
b_servos_bottomleft.text = "BoLe";
|
||||
b_servos_bottomleft.callback = b_servos_bottomleft_cb;
|
||||
gui_button_add(&b_servos_bottomleft);
|
||||
|
||||
b_servos_bottomright.base.x1=b_servos_bottomleft.base.x2+SERVO_BUTTON_SPACING;
|
||||
b_servos_bottomright.base.y1=SERVO_BUTTON_Y-3;
|
||||
b_servos_bottomright.base.x2=AUTO;
|
||||
b_servos_bottomright.base.y2=AUTO;
|
||||
b_servos_bottomright.txtcolor=WHITE;
|
||||
b_servos_bottomright.bgcolor=HEX(0xAE1010);
|
||||
b_servos_bottomright.font=0;
|
||||
b_servos_bottomright.text="BoRi";
|
||||
b_servos_bottomright.callback=b_servos_bottomright_cb;
|
||||
gui_button_add(&b_servos_bottomright);
|
||||
b_servos_bottomright.base.x1 = b_servos_bottomleft.base.x2 + SERVO_BUTTON_SPACING;
|
||||
b_servos_bottomright.base.y1 = SERVO_BUTTON_Y - 3;
|
||||
b_servos_bottomright.base.x2 = AUTO;
|
||||
b_servos_bottomright.base.y2 = AUTO;
|
||||
b_servos_bottomright.txtcolor = WHITE;
|
||||
b_servos_bottomright.bgcolor = HEX(0xAE1010);
|
||||
b_servos_bottomright.font = 0;
|
||||
b_servos_bottomright.text = "BoRi";
|
||||
b_servos_bottomright.callback = b_servos_bottomright_cb;
|
||||
gui_button_add(&b_servos_bottomright);
|
||||
|
||||
//Led Color stuff
|
||||
#define LED_COLOR_BUTTON_Y 35
|
||||
#define LED_COLOR_BUTTON_SPACING 5
|
||||
tft_print_line(5,LED_COLOR_BUTTON_Y,BLACK,TRANSPARENT,0,"Led Color:");
|
||||
//Led Color stuff
|
||||
#define LED_COLOR_BUTTON_Y 35
|
||||
#define LED_COLOR_BUTTON_SPACING 5
|
||||
tft_print_line(5, LED_COLOR_BUTTON_Y, BLACK, TRANSPARENT, 0, "Led Color:");
|
||||
|
||||
b_led_off.base.x1=85;
|
||||
b_led_off.base.y1=LED_COLOR_BUTTON_Y-3;
|
||||
b_led_off.base.x2=AUTO;
|
||||
b_led_off.base.y2=AUTO;
|
||||
b_led_off.txtcolor=WHITE;
|
||||
b_led_off.bgcolor=BLACK;
|
||||
b_led_off.font=0;
|
||||
b_led_off.text="Off";
|
||||
b_led_off.callback=b_led_off_cb;
|
||||
gui_button_add(&b_led_off);
|
||||
b_led_off.base.x1 = 85;
|
||||
b_led_off.base.y1 = LED_COLOR_BUTTON_Y - 3;
|
||||
b_led_off.base.x2 = AUTO;
|
||||
b_led_off.base.y2 = AUTO;
|
||||
b_led_off.txtcolor = WHITE;
|
||||
b_led_off.bgcolor = BLACK;
|
||||
b_led_off.font = 0;
|
||||
b_led_off.text = "Off";
|
||||
b_led_off.callback = b_led_off_cb;
|
||||
gui_button_add(&b_led_off);
|
||||
|
||||
b_led_white.base.x1=b_led_off.base.x2+LED_COLOR_BUTTON_SPACING;
|
||||
b_led_white.base.y1=LED_COLOR_BUTTON_Y-3;
|
||||
b_led_white.base.x2=AUTO;
|
||||
b_led_white.base.y2=AUTO;
|
||||
b_led_white.txtcolor=BLACK;
|
||||
b_led_white.bgcolor=HEX(0xEEEEEE);
|
||||
b_led_white.font=0;
|
||||
b_led_white.text="White";
|
||||
b_led_white.callback=b_led_white_cb;
|
||||
gui_button_add(&b_led_white);
|
||||
b_led_white.base.x1 = b_led_off.base.x2 + LED_COLOR_BUTTON_SPACING;
|
||||
b_led_white.base.y1 = LED_COLOR_BUTTON_Y - 3;
|
||||
b_led_white.base.x2 = AUTO;
|
||||
b_led_white.base.y2 = AUTO;
|
||||
b_led_white.txtcolor = BLACK;
|
||||
b_led_white.bgcolor = HEX(0xEEEEEE);
|
||||
b_led_white.font = 0;
|
||||
b_led_white.text = "White";
|
||||
b_led_white.callback = b_led_white_cb;
|
||||
gui_button_add(&b_led_white);
|
||||
|
||||
b_led_red.base.x1=b_led_white.base.x2+LED_COLOR_BUTTON_SPACING;
|
||||
b_led_red.base.y1=LED_COLOR_BUTTON_Y-3;
|
||||
b_led_red.base.x2=AUTO;
|
||||
b_led_red.base.y2=AUTO;
|
||||
b_led_red.txtcolor=WHITE;
|
||||
b_led_red.bgcolor=HEX(0xEE0000);
|
||||
b_led_red.font=0;
|
||||
b_led_red.text="Red";
|
||||
b_led_red.callback=b_led_red_cb;
|
||||
gui_button_add(&b_led_red);
|
||||
b_led_red.base.x1 = b_led_white.base.x2 + LED_COLOR_BUTTON_SPACING;
|
||||
b_led_red.base.y1 = LED_COLOR_BUTTON_Y - 3;
|
||||
b_led_red.base.x2 = AUTO;
|
||||
b_led_red.base.y2 = AUTO;
|
||||
b_led_red.txtcolor = WHITE;
|
||||
b_led_red.bgcolor = HEX(0xEE0000);
|
||||
b_led_red.font = 0;
|
||||
b_led_red.text = "Red";
|
||||
b_led_red.callback = b_led_red_cb;
|
||||
gui_button_add(&b_led_red);
|
||||
|
||||
b_led_green.base.x1=b_led_red.base.x2+LED_COLOR_BUTTON_SPACING;
|
||||
b_led_green.base.y1=LED_COLOR_BUTTON_Y-3;
|
||||
b_led_green.base.x2=AUTO;
|
||||
b_led_green.base.y2=AUTO;
|
||||
b_led_green.txtcolor=WHITE;
|
||||
b_led_green.bgcolor=HEX(0x00EE00);
|
||||
b_led_green.font=0;
|
||||
b_led_green.text="Green";
|
||||
b_led_green.callback=b_led_green_cb;
|
||||
gui_button_add(&b_led_green);
|
||||
b_led_green.base.x1 = b_led_red.base.x2 + LED_COLOR_BUTTON_SPACING;
|
||||
b_led_green.base.y1 = LED_COLOR_BUTTON_Y - 3;
|
||||
b_led_green.base.x2 = AUTO;
|
||||
b_led_green.base.y2 = AUTO;
|
||||
b_led_green.txtcolor = WHITE;
|
||||
b_led_green.bgcolor = HEX(0x00EE00);
|
||||
b_led_green.font = 0;
|
||||
b_led_green.text = "Green";
|
||||
b_led_green.callback = b_led_green_cb;
|
||||
gui_button_add(&b_led_green);
|
||||
|
||||
b_led_blue.base.x1=b_led_green.base.x2+LED_COLOR_BUTTON_SPACING;
|
||||
b_led_blue.base.y1=LED_COLOR_BUTTON_Y-3;
|
||||
b_led_blue.base.x2=AUTO;
|
||||
b_led_blue.base.y2=AUTO;
|
||||
b_led_blue.txtcolor=WHITE;
|
||||
b_led_blue.bgcolor=HEX(0x0000EE);
|
||||
b_led_blue.font=0;
|
||||
b_led_blue.text="Blue";
|
||||
b_led_blue.callback=b_led_blue_cb;
|
||||
gui_button_add(&b_led_blue);
|
||||
b_led_blue.base.x1 = b_led_green.base.x2 + LED_COLOR_BUTTON_SPACING;
|
||||
b_led_blue.base.y1 = LED_COLOR_BUTTON_Y - 3;
|
||||
b_led_blue.base.x2 = AUTO;
|
||||
b_led_blue.base.y2 = AUTO;
|
||||
b_led_blue.txtcolor = WHITE;
|
||||
b_led_blue.bgcolor = HEX(0x0000EE);
|
||||
b_led_blue.font = 0;
|
||||
b_led_blue.text = "Blue";
|
||||
b_led_blue.callback = b_led_blue_cb;
|
||||
gui_button_add(&b_led_blue);
|
||||
|
||||
//Led MaxPower stuff
|
||||
#define LED_POWER_BUTTON_Y 70
|
||||
tft_print_line(5,LED_POWER_BUTTON_Y,BLACK,TRANSPARENT,0,"Led Maximum Current:");
|
||||
//Led MaxPower stuff
|
||||
#define LED_POWER_BUTTON_Y 70
|
||||
tft_print_line(5, LED_POWER_BUTTON_Y, BLACK, TRANSPARENT, 0, "Led Maximum Current:");
|
||||
|
||||
//Num up down test
|
||||
n_led_powerlimit.x=160;
|
||||
n_led_powerlimit.y=LED_POWER_BUTTON_Y-7;
|
||||
n_led_powerlimit.fgcolor=WHITE;
|
||||
n_led_powerlimit.value = 10;
|
||||
n_led_powerlimit.max=40;
|
||||
n_led_powerlimit.min =0;
|
||||
n_led_powerlimit.callback=n_led_powerlimit_cb;
|
||||
gui_numupdown_add(&n_led_powerlimit);
|
||||
//Num up down test
|
||||
n_led_powerlimit.x = 160;
|
||||
n_led_powerlimit.y = LED_POWER_BUTTON_Y - 7;
|
||||
n_led_powerlimit.fgcolor = WHITE;
|
||||
n_led_powerlimit.value = 10;
|
||||
n_led_powerlimit.max = 40;
|
||||
n_led_powerlimit.min = 0;
|
||||
n_led_powerlimit.callback = n_led_powerlimit_cb;
|
||||
gui_numupdown_add(&n_led_powerlimit);
|
||||
|
||||
|
||||
|
||||
state=detecting;
|
||||
state = detecting;
|
||||
}
|
||||
|
||||
static void leave(void* screen) {
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_servos_center);
|
||||
gui_button_remove(&b_servos_topleft);
|
||||
gui_button_remove(&b_servos_topright);
|
||||
gui_button_remove(&b_servos_bottomleft);
|
||||
gui_button_remove(&b_servos_bottomright);
|
||||
gui_button_remove(&b_led_off);
|
||||
gui_button_remove(&b_led_white);
|
||||
gui_button_remove(&b_led_red);
|
||||
gui_button_remove(&b_led_green);
|
||||
gui_button_remove(&b_led_blue);
|
||||
gui_numupdown_remove(&n_led_powerlimit);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_servos_center);
|
||||
gui_button_remove(&b_servos_topleft);
|
||||
gui_button_remove(&b_servos_topright);
|
||||
gui_button_remove(&b_servos_bottomleft);
|
||||
gui_button_remove(&b_servos_bottomright);
|
||||
gui_button_remove(&b_led_off);
|
||||
gui_button_remove(&b_led_white);
|
||||
gui_button_remove(&b_led_red);
|
||||
gui_button_remove(&b_led_green);
|
||||
gui_button_remove(&b_led_blue);
|
||||
gui_numupdown_remove(&n_led_powerlimit);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void update(void* screen) {
|
||||
switch(state) {
|
||||
case detecting: //Detecting State: Where we try to connect to the pixy
|
||||
if(pixy_init()==0) { //Pixy connection ok
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
pixy_led_set_max_current(10);
|
||||
static void update(void* screen)
|
||||
{
|
||||
switch (state) {
|
||||
case detecting: //Detecting State: Where we try to connect to the pixy
|
||||
if (pixy_init() == 0) { //Pixy connection ok
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
pixy_led_set_max_current(10);
|
||||
|
||||
state = idle; //Go to next state
|
||||
}
|
||||
break;
|
||||
case idle:
|
||||
pixy_service();
|
||||
break;
|
||||
case update_servos:
|
||||
pixy_rcs_set_position(0,servo_x);
|
||||
pixy_rcs_set_position(1,servo_y);
|
||||
state = idle;
|
||||
break;
|
||||
state = idle; //Go to next state
|
||||
}
|
||||
|
||||
case update_ledcolor:
|
||||
{
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("led_set", INT32(led_color), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
state = idle;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case update_ledcurrent:
|
||||
pixy_led_set_max_current(led_maxcurrent);
|
||||
state = idle;
|
||||
break;
|
||||
}
|
||||
case idle:
|
||||
pixy_service();
|
||||
break;
|
||||
|
||||
case update_servos:
|
||||
pixy_rcs_set_position(0, servo_x);
|
||||
pixy_rcs_set_position(1, servo_y);
|
||||
state = idle;
|
||||
break;
|
||||
|
||||
case update_ledcolor: {
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("led_set", INT32(led_color), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
state = idle;
|
||||
}
|
||||
break;
|
||||
|
||||
case update_ledcurrent:
|
||||
pixy_led_set_max_current(led_maxcurrent);
|
||||
state = idle;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_pixytest() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_pixytest()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_pixytest.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
|
||||
* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
|
||||
* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_tracking.c
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
|
||||
* 2015-05-25 timolang@gmail.com 8088014 Updated Tracking Screen so that the implementations are separated into different method groups.
|
||||
* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
|
||||
* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
|
||||
* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
|
||||
* 2015-06-07 aaron@duckpond.ch 3d98ca9 Minor changes
|
||||
* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen_tracking.h"
|
||||
#include "pixy_control.h"
|
||||
#include "button.h"
|
||||
@@ -14,14 +33,16 @@ static CHECKBOX_STRUCT c_frame_toggle; //Checkbox to toggle video data on/off
|
||||
static TOUCH_AREA_STRUCT a_area; //Touch area for the color region selection
|
||||
|
||||
//Callback for when the user presses the "back" button
|
||||
static void b_back_cb(void* button) {
|
||||
gui_screen_back(); //navigate back to the previous screen
|
||||
static void b_back_cb(void* button)
|
||||
{
|
||||
gui_screen_back(); //navigate back to the previous screen
|
||||
}
|
||||
|
||||
static volatile bool frame_visible = false; //Whether or not the video data should be displayed
|
||||
static void c_frame_toggle_cb(void *checkbox, bool checked) {
|
||||
frame_visible=checked; //Set the visibility of the frame to the checked state of the checkbox
|
||||
//Frame will be drawn in the main loop below
|
||||
static void c_frame_toggle_cb(void* checkbox, bool checked)
|
||||
{
|
||||
frame_visible = checked; //Set the visibility of the frame to the checked state of the checkbox
|
||||
//Frame will be drawn in the main loop below
|
||||
}
|
||||
|
||||
static enum {detecting, init, tracking, preselecting, abortselecting, selecting, selected, error} state; //Current state of the screen state machine
|
||||
@@ -31,12 +52,13 @@ static POINT_STRUCT point2; //End point of the rectangle selected by the user (c
|
||||
static bool point1_valid; //Whether or not we have a valid first point
|
||||
|
||||
//Callback for when the user presses the "select color" button
|
||||
static void b_select_cb(void* button) {
|
||||
if(state==selecting) { //we're currently selecting a color region
|
||||
state = abortselecting; //Abort selecting!!
|
||||
} else if (state==tracking) { //we're currently watching the tracking
|
||||
state = preselecting; //start selecting
|
||||
}
|
||||
static void b_select_cb(void* button)
|
||||
{
|
||||
if (state == selecting) { //we're currently selecting a color region
|
||||
state = abortselecting; //Abort selecting!!
|
||||
} else if (state == tracking) { //we're currently watching the tracking
|
||||
state = preselecting; //start selecting
|
||||
}
|
||||
}
|
||||
|
||||
//Video Region properties
|
||||
@@ -50,34 +72,38 @@ static void b_select_cb(void* button) {
|
||||
|
||||
//Callback for when the user touches the frame area to select a color region.
|
||||
//Note: It doesn't matter in which direction the user draws the rectangle, we'll normalize the coordinates later
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
|
||||
POINT_STRUCT p = touch_get_last_point();
|
||||
switch(triggeredAction) {
|
||||
case PEN_DOWN: //The user just put down the pen
|
||||
point1.x = p.x-FRAME_START_X; //Calculate x-Coordinate relative to frame start
|
||||
point1.y = p.y-FRAME_START_Y; //Calculate y-Coordinate relative to frame start
|
||||
point1_valid= true; //The point1 is now valid
|
||||
break;
|
||||
case PEN_UP: //The user took the pen away
|
||||
if(point1_valid) { //only execute if point1 is valid
|
||||
point2.x = p.x-FRAME_START_X; //Calculate x-Coordinate relative to frame start
|
||||
point2.y = p.y-FRAME_START_Y; //Calculate y-Coordinate relative to frame start
|
||||
state = selected;
|
||||
}
|
||||
break;
|
||||
}
|
||||
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
|
||||
{
|
||||
POINT_STRUCT p = touch_get_last_point();
|
||||
|
||||
switch (triggeredAction) {
|
||||
case PEN_DOWN: //The user just put down the pen
|
||||
point1.x = p.x - FRAME_START_X; //Calculate x-Coordinate relative to frame start
|
||||
point1.y = p.y - FRAME_START_Y; //Calculate y-Coordinate relative to frame start
|
||||
point1_valid = true; //The point1 is now valid
|
||||
break;
|
||||
|
||||
case PEN_UP: //The user took the pen away
|
||||
if (point1_valid) { //only execute if point1 is valid
|
||||
point2.x = p.x - FRAME_START_X; //Calculate x-Coordinate relative to frame start
|
||||
point2.y = p.y - FRAME_START_Y; //Calculate y-Coordinate relative to frame start
|
||||
state = selected;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Prototype for tracking start/stop methods
|
||||
typedef void (*TRACKING_VOID_CALLBACK)(void* tracking_config);
|
||||
//Prototype for tracking update method
|
||||
typedef void (*TRACKING_BLOCK_CALLBACK)(void* tracking_config, struct Block* blocks, int num_blocks );
|
||||
typedef void (*TRACKING_BLOCK_CALLBACK)(void* tracking_config, struct Block* blocks, int num_blocks);
|
||||
|
||||
//Structure to save callbacks and settings of a tracking implementation
|
||||
typedef struct {
|
||||
TRACKING_VOID_CALLBACK start;
|
||||
TRACKING_VOID_CALLBACK stop;
|
||||
TRACKING_BLOCK_CALLBACK update;
|
||||
TRACKING_VOID_CALLBACK start;
|
||||
TRACKING_VOID_CALLBACK stop;
|
||||
TRACKING_BLOCK_CALLBACK update;
|
||||
} TRACKING_CONFIG_STRUCT;
|
||||
|
||||
//Methods for our tracking implementation ahead
|
||||
@@ -85,45 +111,48 @@ static int16_t servo_x = 0;
|
||||
static int16_t servo_y = 0;
|
||||
|
||||
//Method/Callback to start our tracking
|
||||
void tracking_our_start(void* tracking_config) {
|
||||
//Activate pixy's data send program
|
||||
int32_t response;
|
||||
int return_value;
|
||||
void tracking_our_start(void* tracking_config)
|
||||
{
|
||||
//Activate pixy's data send program
|
||||
int32_t response;
|
||||
int return_value;
|
||||
|
||||
servo_x = servo_y = 500; // set a default value of 500
|
||||
pixy_rcs_set_position(0, servo_x); // set default
|
||||
pixy_rcs_set_position(0, servo_x); // set default
|
||||
pixy_rcs_set_position(1, servo_y); // set default
|
||||
|
||||
return_value = pixy_command("runprog", INT8(0), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
return_value = pixy_command("runprog", INT8(0), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
}
|
||||
|
||||
//Method/Callback to stop our tracking
|
||||
void tracking_our_stop(void* tracking_config) {
|
||||
//Stop pixy's data send programm
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
void tracking_our_stop(void* tracking_config)
|
||||
{
|
||||
//Stop pixy's data send programm
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
}
|
||||
|
||||
//Method/Callback to calculate one step of our tracking
|
||||
void tracking_our_update(void* tracking_config, struct Block* blocks, int num_blocks) {
|
||||
void tracking_our_update(void* tracking_config, struct Block* blocks, int num_blocks)
|
||||
{
|
||||
|
||||
if(num_blocks <= 0){ // Check if there are blocks available
|
||||
if (num_blocks <= 0) { // Check if there are blocks available
|
||||
return; // When there are none, do nothing
|
||||
}
|
||||
|
||||
|
||||
uint16_t x = blocks[0].x; // Get x coordinate of the biggest object
|
||||
uint16_t y = blocks[0].y; // Get y coordinate of the biggest object
|
||||
|
||||
int16_t xset = 0;
|
||||
int16_t xset = 0;
|
||||
int16_t yset = 0;
|
||||
|
||||
xset = (servo_x + pixy_PID_X((FRAME_WIDTH / 2), x)); // calculate the PID output for x
|
||||
yset = (servo_y - pixy_PID_Y((FRAME_HEIGHT / 2), y)); // calculate the PID output for y
|
||||
|
||||
|
||||
xset = (xset < 0) ? 0 : xset; // x lower boundary check
|
||||
xset = (xset > 1000) ? 1000 : xset; // x upper boundary check
|
||||
|
||||
|
||||
yset = (yset < 0) ? 0 : yset; // y lower boundary check
|
||||
yset = (yset > 1000) ? 1000 : yset; // y upper boundary check
|
||||
|
||||
@@ -136,245 +165,257 @@ void tracking_our_update(void* tracking_config, struct Block* blocks, int num_bl
|
||||
|
||||
//Variable which stores all the callbacks and settings for our tracking implementation
|
||||
static TRACKING_CONFIG_STRUCT tracking_our = {
|
||||
tracking_our_start,
|
||||
tracking_our_stop,
|
||||
tracking_our_update
|
||||
tracking_our_start,
|
||||
tracking_our_stop,
|
||||
tracking_our_update
|
||||
};
|
||||
|
||||
//Methods for reference tracking implementation ahead
|
||||
|
||||
//Method/Callback to start reference tracking
|
||||
void tracking_reference_start(void* tracking_config) {
|
||||
//Run reference tracking
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("runprog", INT8(2), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
void tracking_reference_start(void* tracking_config)
|
||||
{
|
||||
//Run reference tracking
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("runprog", INT8(2), END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
}
|
||||
|
||||
//Method/Callback to stop reference tracking
|
||||
void tracking_reference_stop(void* tracking_config) {
|
||||
//Stop reference tracking
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
void tracking_reference_stop(void* tracking_config)
|
||||
{
|
||||
//Stop reference tracking
|
||||
int32_t response;
|
||||
int return_value;
|
||||
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
|
||||
}
|
||||
|
||||
//Method/Callback to calculate one step of the reference tracking
|
||||
void tracking_reference_update(void* tracking_config, struct Block* blocks, int num_blocks) {
|
||||
//Nothing to do here. Pixy does it all.
|
||||
void tracking_reference_update(void* tracking_config, struct Block* blocks, int num_blocks)
|
||||
{
|
||||
//Nothing to do here. Pixy does it all.
|
||||
}
|
||||
|
||||
//Variable which stores all the callbacks and settings for the reference tracking implementation
|
||||
static TRACKING_CONFIG_STRUCT tracking_reference = {
|
||||
tracking_reference_start,
|
||||
tracking_reference_stop,
|
||||
tracking_reference_update
|
||||
tracking_reference_start,
|
||||
tracking_reference_stop,
|
||||
tracking_reference_update
|
||||
};
|
||||
|
||||
//Pointer to the currently active tracking implementation. See also tracking_set_mode
|
||||
static TRACKING_CONFIG_STRUCT* tracking_current;
|
||||
|
||||
//Method to set the current tracking implementation. This function is exported and should be called before getting the screen
|
||||
void tracking_set_mode(enum Tracking_Implementation impl) {
|
||||
//Depending on the enum value let tracking_current point to a different setting/callback structure
|
||||
switch(impl) {
|
||||
case OUR_TRACKING:
|
||||
tracking_current = &tracking_our;
|
||||
break;
|
||||
case REFERENCE_TRACKING:
|
||||
tracking_current = &tracking_reference;
|
||||
break;
|
||||
default:
|
||||
tracking_current=NULL;
|
||||
break;
|
||||
}
|
||||
void tracking_set_mode(enum Tracking_Implementation impl)
|
||||
{
|
||||
//Depending on the enum value let tracking_current point to a different setting/callback structure
|
||||
switch (impl) {
|
||||
case OUR_TRACKING:
|
||||
tracking_current = &tracking_our;
|
||||
break;
|
||||
|
||||
case REFERENCE_TRACKING:
|
||||
tracking_current = &tracking_reference;
|
||||
break;
|
||||
|
||||
default:
|
||||
tracking_current = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Callback for when the screen is entered/loaded
|
||||
static void enter(void* screen) {
|
||||
tft_clear(WHITE);
|
||||
|
||||
//"Back" button
|
||||
b_back.base.x1=5; //Start X of Button
|
||||
b_back.base.y1=5; //Start Y of Button
|
||||
b_back.base.x2=AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor=WHITE; //Set foreground color
|
||||
b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font=0; //Select Font
|
||||
b_back.text="Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback=b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
static void enter(void* screen)
|
||||
{
|
||||
tft_clear(WHITE);
|
||||
|
||||
//"Back" button
|
||||
b_back.base.x1 = 5; //Start X of Button
|
||||
b_back.base.y1 = 5; //Start Y of Button
|
||||
b_back.base.x2 = AUTO; //Auto Calculate X2 with String Width
|
||||
b_back.base.y2 = AUTO; //Auto Calculate Y2 with String Height
|
||||
b_back.txtcolor = WHITE; //Set foreground color
|
||||
b_back.bgcolor = HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
|
||||
b_back.font = 0; //Select Font
|
||||
b_back.text = "Back"; //Set Text (For formatted strings take sprintf)
|
||||
b_back.callback = b_back_cb; //Call b_back_cb as Callback
|
||||
gui_button_add(&b_back); //Register Button (and run the callback from now on)
|
||||
|
||||
|
||||
//"Select color" button
|
||||
b_select.base.x1=150;
|
||||
b_select.base.y1=5;
|
||||
b_select.base.x2=AUTO;
|
||||
b_select.base.y2=AUTO;
|
||||
b_select.txtcolor=WHITE;
|
||||
b_select.bgcolor=HEX(0xAE1010);
|
||||
b_select.font=0;
|
||||
b_select.text="Select Color";
|
||||
b_select.callback=b_select_cb;
|
||||
gui_button_add(&b_select);
|
||||
//"Select color" button
|
||||
b_select.base.x1 = 150;
|
||||
b_select.base.y1 = 5;
|
||||
b_select.base.x2 = AUTO;
|
||||
b_select.base.y2 = AUTO;
|
||||
b_select.txtcolor = WHITE;
|
||||
b_select.bgcolor = HEX(0xAE1010);
|
||||
b_select.font = 0;
|
||||
b_select.text = "Select Color";
|
||||
b_select.callback = b_select_cb;
|
||||
gui_button_add(&b_select);
|
||||
|
||||
//"Frame visible" checkbox
|
||||
c_frame_toggle.base.x1 = 50;
|
||||
c_frame_toggle.base.x2 = 50+16;
|
||||
c_frame_toggle.base.y1 = 5;
|
||||
c_frame_toggle.base.y2 = 5+16;
|
||||
c_frame_toggle.checked = frame_visible;
|
||||
c_frame_toggle.fgcolor = CHECKBOX_WIN_FG_COLOR;
|
||||
c_frame_toggle.callback = c_frame_toggle_cb;
|
||||
gui_checkbox_add(&c_frame_toggle);
|
||||
tft_print_line(73,8,BLACK,TRANSPARENT,0,"Show Video");
|
||||
//"Frame visible" checkbox
|
||||
c_frame_toggle.base.x1 = 50;
|
||||
c_frame_toggle.base.x2 = 50 + 16;
|
||||
c_frame_toggle.base.y1 = 5;
|
||||
c_frame_toggle.base.y2 = 5 + 16;
|
||||
c_frame_toggle.checked = frame_visible;
|
||||
c_frame_toggle.fgcolor = CHECKBOX_WIN_FG_COLOR;
|
||||
c_frame_toggle.callback = c_frame_toggle_cb;
|
||||
gui_checkbox_add(&c_frame_toggle);
|
||||
tft_print_line(73, 8, BLACK, TRANSPARENT, 0, "Show Video");
|
||||
|
||||
|
||||
//Area to select a "color region"
|
||||
a_area.hookedActions = PEN_DOWN | PEN_UP;
|
||||
a_area.x1 = FRAME_START_X;
|
||||
a_area.y1 = FRAME_START_Y;
|
||||
a_area.x2 = FRAME_END_X;
|
||||
a_area.y2 = FRAME_END_Y;
|
||||
a_area.callback = touchCB;
|
||||
//Area to select a "color region"
|
||||
a_area.hookedActions = PEN_DOWN | PEN_UP;
|
||||
a_area.x1 = FRAME_START_X;
|
||||
a_area.y1 = FRAME_START_Y;
|
||||
a_area.x2 = FRAME_END_X;
|
||||
a_area.y2 = FRAME_END_Y;
|
||||
a_area.callback = touchCB;
|
||||
//Do not register it here, we do that later
|
||||
|
||||
if(tracking_current==NULL) {
|
||||
state = error;
|
||||
} else {
|
||||
state = detecting; //Start with the detecting state
|
||||
}
|
||||
if (tracking_current == NULL) {
|
||||
state = error;
|
||||
} else {
|
||||
state = detecting; //Start with the detecting state
|
||||
}
|
||||
}
|
||||
|
||||
//Callback for when the screen is left/unloaded
|
||||
static void leave(void* screen) {
|
||||
//Remove buttons and checkbox
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_select);
|
||||
gui_checkbox_remove(&c_frame_toggle);
|
||||
static void leave(void* screen)
|
||||
{
|
||||
//Remove buttons and checkbox
|
||||
gui_button_remove(&b_back);
|
||||
gui_button_remove(&b_select);
|
||||
gui_checkbox_remove(&c_frame_toggle);
|
||||
|
||||
if(state==selecting) { //the user left the screen in the "selecting" phase
|
||||
touch_unregister_area(&a_area); //remove the touch area
|
||||
}
|
||||
if (state == selecting) { //the user left the screen in the "selecting" phase
|
||||
touch_unregister_area(&a_area); //remove the touch area
|
||||
}
|
||||
|
||||
if(state==tracking) { //the user left the screen in the "tracking" phase
|
||||
tracking_current->stop(tracking_current); //stop tracking
|
||||
pixy_led_set_RGB(0,0,0);
|
||||
}
|
||||
if (state == tracking) { //the user left the screen in the "tracking" phase
|
||||
tracking_current->stop(tracking_current); //stop tracking
|
||||
pixy_led_set_RGB(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//Callback for when the screen should be updated
|
||||
//This is the main loop of the screen. This method will be called repeatedly
|
||||
static void update(void* screen) {
|
||||
switch(state) {
|
||||
case detecting: //Detecting State: Where we try to connect to the pixy
|
||||
if(pixy_init()==0) { //Pixy connection ok
|
||||
state = init; //Go to next state
|
||||
}
|
||||
break;
|
||||
static void update(void* screen)
|
||||
{
|
||||
switch (state) {
|
||||
case detecting: //Detecting State: Where we try to connect to the pixy
|
||||
if (pixy_init() == 0) { //Pixy connection ok
|
||||
state = init; //Go to next state
|
||||
}
|
||||
|
||||
case init: //Init State: Where we start the tracking
|
||||
tracking_current->start(tracking_current);
|
||||
state=tracking;
|
||||
break;
|
||||
break;
|
||||
|
||||
case tracking: //Tracking state: Where we render the frame and the tracked objects
|
||||
pixy_service(); //Receive events (e.g. block-data) from pixy
|
||||
case init: //Init State: Where we start the tracking
|
||||
tracking_current->start(tracking_current);
|
||||
state = tracking;
|
||||
break;
|
||||
|
||||
if(pixy_blocks_are_new()) { //There are new blocks available
|
||||
if(frame_visible) { //If the user want's us to draw the video data
|
||||
pixy_render_full_frame(FRAME_START_X,FRAME_START_Y);
|
||||
} else { //the user want's a colored background
|
||||
tft_fill_rectangle(FRAME_START_X,FRAME_START_Y,FRAME_END_X,FRAME_END_Y,RGB(200,200,200));
|
||||
}
|
||||
case tracking: //Tracking state: Where we render the frame and the tracked objects
|
||||
pixy_service(); //Receive events (e.g. block-data) from pixy
|
||||
|
||||
#define BLOCK_BUFFER_SIZE 5 //The maximum amount of blocks that we want to receive
|
||||
struct Block blocks[BLOCK_BUFFER_SIZE]; //Storage to receive blocks from pixy
|
||||
int blocks_received= pixy_get_blocks(BLOCK_BUFFER_SIZE,blocks); //Try to receive up to BLOCK_BUFFER_SIZE Blocks from pixy
|
||||
if (pixy_blocks_are_new()) { //There are new blocks available
|
||||
if (frame_visible) { //If the user want's us to draw the video data
|
||||
pixy_render_full_frame(FRAME_START_X, FRAME_START_Y);
|
||||
} else { //the user want's a colored background
|
||||
tft_fill_rectangle(FRAME_START_X, FRAME_START_Y, FRAME_END_X, FRAME_END_Y, RGB(200, 200, 200));
|
||||
}
|
||||
|
||||
if(blocks_received>=0) { //block receiving ok
|
||||
tracking_current->update(tracking_current,blocks,blocks_received); //apply tracking
|
||||
#define BLOCK_BUFFER_SIZE 5 //The maximum amount of blocks that we want to receive
|
||||
struct Block blocks[BLOCK_BUFFER_SIZE]; //Storage to receive blocks from pixy
|
||||
int blocks_received = pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks); //Try to receive up to BLOCK_BUFFER_SIZE Blocks from pixy
|
||||
|
||||
//Draw blocks
|
||||
for(int i=0; i<blocks_received; i++) { //for each received block
|
||||
struct Block* block = &(blocks[i]);
|
||||
//block.x and block.y are the center coordinates of the object relative to the camera origin.
|
||||
uint16_t x = block->x-1+FRAME_START_X -block->width/2; //Calculate x-Coordinate on the display
|
||||
uint16_t y = block->y-1+FRAME_START_Y -block->height/2; //Calculate y-Coordinate on the display
|
||||
tft_draw_rectangle(x,y,x+block->width-1, y+block->height-1,WHITE); //Draw a white rectangle
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (blocks_received >= 0) { //block receiving ok
|
||||
tracking_current->update(tracking_current, blocks, blocks_received); //apply tracking
|
||||
|
||||
case preselecting: //Pre-Selecting State: Where we set up the color region selection
|
||||
{
|
||||
tracking_current->stop(tracking_current); //Stop tracking
|
||||
//Draw blocks
|
||||
for (int i = 0; i < blocks_received; i++) { //for each received block
|
||||
struct Block* block = &(blocks[i]);
|
||||
//block.x and block.y are the center coordinates of the object relative to the camera origin.
|
||||
uint16_t x = block->x - 1 + FRAME_START_X - block->width / 2; //Calculate x-Coordinate on the display
|
||||
uint16_t y = block->y - 1 + FRAME_START_Y - block->height / 2; //Calculate y-Coordinate on the display
|
||||
tft_draw_rectangle(x, y, x + block->width - 1, y + block->height - 1, WHITE); //Draw a white rectangle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixy_render_full_frame(FRAME_START_X,FRAME_START_Y); //Render one frame
|
||||
break;
|
||||
|
||||
touch_register_area(&a_area); //Register touch area and receive events from now on
|
||||
point1_valid=false; //we start with an invalid point1
|
||||
case preselecting: { //Pre-Selecting State: Where we set up the color region selection
|
||||
tracking_current->stop(tracking_current); //Stop tracking
|
||||
|
||||
b_select.text="Abort"; //Change the button text to "Abort"
|
||||
gui_button_redraw(&b_select); //redraw button
|
||||
pixy_render_full_frame(FRAME_START_X, FRAME_START_Y); //Render one frame
|
||||
|
||||
state = selecting; //The user can now select a region
|
||||
}
|
||||
break;
|
||||
touch_register_area(&a_area); //Register touch area and receive events from now on
|
||||
point1_valid = false; //we start with an invalid point1
|
||||
|
||||
case selected: //Selected State: Where we send the users selection to pixy
|
||||
{
|
||||
//Ensure that (x1,y1) represent the top-left point and (x2,y2) the bottom-right.
|
||||
unsigned int tmp;
|
||||
if(point1.x > point2.x){
|
||||
tmp = point1.x;
|
||||
point1.x = point2.x;
|
||||
point2.x = tmp;
|
||||
}
|
||||
b_select.text = "Abort"; //Change the button text to "Abort"
|
||||
gui_button_redraw(&b_select); //redraw button
|
||||
|
||||
if(point1.y > point2.y){
|
||||
tmp = point1.y;
|
||||
point1.y = point2.y;
|
||||
point2.y = tmp;
|
||||
}
|
||||
//Send pixy the selected region
|
||||
pixy_cc_set_region(1,point1.x,point1.y,point2.x-point1.x,point2.y-point1.y);
|
||||
}
|
||||
//no break here: We want the following code to be executed as well
|
||||
state = selecting; //The user can now select a region
|
||||
}
|
||||
break;
|
||||
|
||||
case abortselecting: //Abort-Selecting State: Where we deinitialize the stuff we used for region selection
|
||||
{
|
||||
touch_unregister_area(&a_area); //Remove the touch area. We'll no longer receive touch events
|
||||
case selected: { //Selected State: Where we send the users selection to pixy
|
||||
//Ensure that (x1,y1) represent the top-left point and (x2,y2) the bottom-right.
|
||||
unsigned int tmp;
|
||||
|
||||
b_select.text="Select Color"; //Change the button text back to "Select Color"
|
||||
gui_button_redraw(&b_select); //redraw button
|
||||
if (point1.x > point2.x) {
|
||||
tmp = point1.x;
|
||||
point1.x = point2.x;
|
||||
point2.x = tmp;
|
||||
}
|
||||
|
||||
tracking_current->start(tracking_current); //Start tracking again
|
||||
state=tracking;
|
||||
}
|
||||
break;
|
||||
if (point1.y > point2.y) {
|
||||
tmp = point1.y;
|
||||
point1.y = point2.y;
|
||||
point2.y = tmp;
|
||||
}
|
||||
|
||||
case selecting: //Selecting State: Where we wait on the user to select a color region
|
||||
pixy_service(); //receive pixy events
|
||||
//wait on user to select the image area
|
||||
break;
|
||||
//Send pixy the selected region
|
||||
pixy_cc_set_region(1, point1.x, point1.y, point2.x - point1.x, point2.y - point1.y);
|
||||
}
|
||||
|
||||
case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
|
||||
//wait on user to click the back button
|
||||
break;
|
||||
}
|
||||
//no break here: We want the following code to be executed as well
|
||||
|
||||
case abortselecting: { //Abort-Selecting State: Where we deinitialize the stuff we used for region selection
|
||||
touch_unregister_area(&a_area); //Remove the touch area. We'll no longer receive touch events
|
||||
|
||||
b_select.text = "Select Color"; //Change the button text back to "Select Color"
|
||||
gui_button_redraw(&b_select); //redraw button
|
||||
|
||||
tracking_current->start(tracking_current); //Start tracking again
|
||||
state = tracking;
|
||||
}
|
||||
break;
|
||||
|
||||
case selecting: //Selecting State: Where we wait on the user to select a color region
|
||||
pixy_service(); //receive pixy events
|
||||
//wait on user to select the image area
|
||||
break;
|
||||
|
||||
case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
|
||||
//wait on user to click the back button
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Declare screen callbacks
|
||||
static SCREEN_STRUCT screen = {
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
enter,
|
||||
leave,
|
||||
update
|
||||
};
|
||||
|
||||
|
||||
SCREEN_STRUCT* get_screen_tracking() {
|
||||
return &screen;
|
||||
SCREEN_STRUCT* get_screen_tracking()
|
||||
{
|
||||
return &screen;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/**************************************************************************************************************************************
|
||||
* Project: discoverpixy
|
||||
* Website: https://github.com/t-moe/discoverpixy
|
||||
* Authors: Aaron Schmocker, Timo Lang
|
||||
* Institution: BFH Bern University of Applied Sciences
|
||||
* File: common/app/screen_tracking.h
|
||||
*
|
||||
* Version History:
|
||||
* Date Autor Email SHA Changes
|
||||
* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
|
||||
*
|
||||
**************************************************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/**
|
||||
@@ -16,8 +29,8 @@
|
||||
* Enum which contains the available tracking implementations
|
||||
*/
|
||||
enum Tracking_Implementation {
|
||||
OUR_TRACKING, //!< Our own tracking PID implementation
|
||||
REFERENCE_TRACKING//!< Pixy's internal tracking implementation
|
||||
OUR_TRACKING, //!< Our own tracking PID implementation
|
||||
REFERENCE_TRACKING//!< Pixy's internal tracking implementation
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user