Commit 5fcffdf0 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk Committed by Projects

adding compass app

parent bb68b1fd
This diff is collapsed.
...@@ -10,15 +10,17 @@ struct rle_bitmap ...@@ -10,15 +10,17 @@ struct rle_bitmap
const uint8_t *data; const uint8_t *data;
}; };
extern const struct rle_bitmap gps_disconnected; extern const struct rle_bitmap comp_circle;
extern const struct rle_bitmap date_icon;
extern const struct rle_bitmap gps_receiving;
extern const struct rle_bitmap battery; extern const struct rle_bitmap battery;
extern const struct rle_bitmap clock_icon;
extern const struct rle_bitmap example_icon;
extern const struct rle_bitmap battery_charging; extern const struct rle_bitmap battery_charging;
extern const struct rle_bitmap gps_searching; extern const struct rle_bitmap gps_searching;
extern const struct rle_bitmap settings_icon; extern const struct rle_bitmap comp_ico;
extern const struct rle_bitmap compass_arrow; extern const struct rle_bitmap gps_disconnected;
extern const struct rle_bitmap comp_arrow;
extern const struct rle_bitmap comp_circle2;
extern const struct rle_bitmap gps_receiving;
extern const struct rle_bitmap comp_arrow2;
extern const struct rle_bitmap comp_circle3;
extern const struct rle_bitmap example_icon;
#endif /* BITMAPS_H */ #endif /* BITMAPS_H */
sw/bitmaps/example_icon.bmp

842 Bytes | W: | H:

sw/bitmaps/example_icon.bmp

774 Bytes | W: | H:

sw/bitmaps/example_icon.bmp
sw/bitmaps/example_icon.bmp
sw/bitmaps/example_icon.bmp
sw/bitmaps/example_icon.bmp
  • 2-up
  • Swipe
  • Onion skin
...@@ -117,6 +117,8 @@ INCLUDEPATHS += \ ...@@ -117,6 +117,8 @@ INCLUDEPATHS += \
-I../common/CMSIS/Include \ -I../common/CMSIS/Include \
-I../common/Device/EnergyMicro/EFM32GG/Include \ -I../common/Device/EnergyMicro/EFM32GG/Include \
-I../common \ -I../common \
-I../common/usb \
-I../common/usb/inc \
-I../common/emlib/inc \ -I../common/emlib/inc \
-I../common/emdrv/sleep/inc \ -I../common/emdrv/sleep/inc \
...@@ -167,6 +169,14 @@ C_SRC += \ ...@@ -167,6 +169,14 @@ C_SRC += \
../common/gfx/graphics.c \ ../common/gfx/graphics.c \
../common/gfx/gfx.c \ ../common/gfx/gfx.c \
../common/gfx/ui.c \ ../common/gfx/ui.c \
../common/sincos.c \
../common/usb/src/em_usbd.c \
../common/usb/src/em_usbdch9.c \
../common/usb/src/em_usbhal.c \
../common/usb/src/em_usbdep.c \
../common/usb/src/em_usbdint.c \
../common/usb/src/em_usbtimer.c \
../common/usb/usbdesc.c \
FreeRTOS/Source/timers.c \ FreeRTOS/Source/timers.c \
FreeRTOS/Source/tasks.c \ FreeRTOS/Source/tasks.c \
FreeRTOS/Source/queue.c \ FreeRTOS/Source/queue.c \
......
...@@ -29,18 +29,55 @@ ...@@ -29,18 +29,55 @@
#include <drivers/LSM303C/lsm303c.h> #include <drivers/LSM303C/lsm303c.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <sincos.h> #include <sincos.h>
#include <usbdesc.h>
#define COMPASS_R 50 #define COMP_R 50.0
#define COMPASS_X0 64 #define COMP_X0 64
#define COMPASS_Y0 64 #define COMP_Y0 64
static int x_lcd, y_lcd; static int x_lcd, y_lcd;
static float sina, cosa;
static int calib;
lsm303_smpl iron;
static void compass_redraw(struct ui_widget *w) static void compass_redraw(struct ui_widget *w)
{ {
static int angle, ff;
int arr_h, arr_w, cir_h, cir_w;
char buf[20];
arr_h = comp_arrow2.h;
arr_w = comp_arrow2.w;
cir_h = comp_circle2.h;
cir_w = comp_circle2.w;
//if(angle == 0) ff=1;
//else if(angle == 180) ff=0;
//if(ff) angle += 10;
//else angle -= 10;
//sina = 2; cosa = 2;
//angle +=1;
//if(angle == 180) angle=-180;
gfx_clear(&w->dc, 0); gfx_clear(&w->dc, 0);
//gfx_draw_bitmap(&w->dc, 64, 64, &compass_arrow); //gfx_line(&w->dc, COMP_X0, COMP_Y0, x_lcd, y_lcd, 1);
gfx_line(&w->dc, COMPASS_X0, COMPASS_Y0, x_lcd, y_lcd, 1); if(!calib) {
gfx_draw_bitmap(&w->dc, COMP_X0-cir_w/2, COMP_Y0-cir_h/2, &comp_circle2);
gfx_draw_bitmap_rotate(&w->dc, COMP_X0-arr_w/2, COMP_Y0-arr_h/2, &comp_arrow2,
COMP_X0, COMP_Y0, angle, sina, cosa);
}
if(calib==1) {
sprintf(buf, "Calibration");
gfx_centered_text(&w->dc, &font_helv17, 60, buf, COLOR_BLACK);
}
if(calib==2) {
sprintf(buf, "ix: %d", iron.x);
gfx_text(&w->dc, &font_helv17, 10, 30, buf, COLOR_BLACK);
sprintf(buf, "iy: %d", iron.y);
gfx_text(&w->dc, &font_helv17, 10, 60, buf, COLOR_BLACK);
sprintf(buf, "iz: %d", iron.z);
gfx_text(&w->dc, &font_helv17, 10, 90, buf, COLOR_BLACK);
}
} }
static void compass_event(struct ui_widget *w, const struct event *evt) static void compass_event(struct ui_widget *w, const struct event *evt)
...@@ -69,12 +106,15 @@ void compass_main(void *params) ...@@ -69,12 +106,15 @@ void compass_main(void *params)
(void)(params); (void)(params);
struct event evt; struct event evt;
lsm303_smpl acc, mag; lsm303_smpl acc, mag;
int pitch, roll, xh, yh, x_comp, y_comp; lsm303_smpl c_max, c_min;
int pitch, roll, xh, yh, th, x_comp, y_comp;
unsigned int x2, y2, z2; unsigned int x2, y2, z2;
float xy_mean; float xy_mean;
char buf[50];
/*lsm303 init, we need both ACC & MAG for tilt/roll compensation*/ /*lsm303 init, we need both ACC & MAG for tilt/roll compensation*/
lsm303_init(); lsm303_init();
USBD_Init(&initstruct);
ui_clear(); ui_clear();
ui_init_widget(&compass_screen); ui_init_widget(&compass_screen);
...@@ -97,32 +137,68 @@ void compass_main(void *params) ...@@ -97,32 +137,68 @@ void compass_main(void *params)
case BUTTON_PRESSED: case BUTTON_PRESSED:
if(evt.data.button == BUT_TR) if(evt.data.button == BUT_TR)
return; return;
if(evt.data.button == BUT_BR) {
c_min.x = 0x7fff;
c_min.y = 0x7fff;
c_min.z = 0x7fff;
c_max.x = -0x7fff;
c_max.y = -0x7fff;
c_max.z = -0x7fff;
calib = 1;
}
if(evt.data.button == BUT_BL && calib) {
iron = lsm303_calib_iron(&c_max, &c_min);
calib = 2;
}
if(evt.data.button == BUT_TL && calib==2) {
calib = 0;
}
} }
} }
else { else {
lsm303_get_sample(DEV_ACC, &acc); lsm303_get_sample(DEV_ACC, &acc);
lsm303_get_sample(DEV_MAG, &mag); lsm303_get_sample(DEV_MAG, &mag);
/* calculate pitch and roll from accelerometer */ if(calib==1) {
x2 = acc.x * acc.x; /* we try to find min and max for axis to calibrate */
y2 = acc.y * acc.y; if(mag.x > c_max.x) c_max.x = mag.x;
z2 = acc.z * acc.z; if(mag.x < c_min.x) c_min.x = mag.x;
pitch = -small_atan(acc.x, small_sqrt(acc.y*acc.y + acc.z*acc.z)); if(mag.y > c_max.y) c_max.y = mag.y;
roll = small_atan(acc.y, small_sqrt(acc.x*acc.x + acc.z*acc.z)); if(mag.y < c_min.y) c_min.y = mag.y;
/* work with compass readout, first revert it because magnetic south is north */ if(mag.z > c_max.z) c_max.z = mag.z;
mag.x *= -1; if(mag.z < c_min.z) c_min.z = mag.z;
mag.y *= -1; }
mag.z *= -1; if(!calib) {
/*now calculate heading based on MAG readout and pinch/roll*/ /* calculate pitch and roll from accelerometer */
xh = mag.x*small_cos(pitch) + mag.z*small_sin(pitch); x2 = acc.x * acc.x;
yh = mag.x*small_sin(roll)*small_sin(pitch) + mag.y*small_cos(roll) - y2 = acc.y * acc.y;
mag.z*small_sin(roll)*small_cos(pitch); z2 = acc.z * acc.z;
/* calculate x,y for compass in cartesian */ pitch = -small_atan(acc.x, small_sqrt(acc.y*acc.y + acc.z*acc.z));
xy_mean = small_sqrt(xh*xh + yh*yh); roll = small_atan(acc.y, small_sqrt(acc.x*acc.x + acc.z*acc.z));
x_comp = COMPASS_R*yh / xy_mean; sprintf(buf, "p: %d, r: %d\n\r", pitch, roll);
y_comp = COMPASS_R*xh / xy_mean; USBD_Write(USBDESC_EP_DATA_OUT, (void*)buf, strlen(buf), NULL);
/* transform to LCD coordinates */ /* work with compass readout, first revert it because magnetic south is north */
x_lcd = x_comp + COMPASS_X0; mag.x *= -1;
y_lcd = -y_comp + COMPASS_Y0; mag.y *= -1;
mag.z *= -1;
/*now calculate heading based on MAG readout and pinch/roll*/
xh = (int)((float)mag.x*small_cos(pitch) + (float)mag.z*small_sin(pitch));
yh = (int)((float)mag.x*small_sin(roll)*small_sin(pitch) + (float)mag.y*small_cos(roll) -
(float)mag.z*small_sin(roll)*small_cos(pitch));
/* LCD is rotated 90 degrees, so xh = yh and yh=-xh */
th = xh;
xh = yh;
yh = -th;
/* calculate x,y for compass in cartesian */
xy_mean = small_sqrt(xh*xh + yh*yh);
x_comp = (int)((float)COMP_R*yh / xy_mean);
y_comp = (int)((float)COMP_R*xh / xy_mean);
/* transform to LCD coordinates */
x_lcd = x_comp + COMP_X0;
y_lcd = -y_comp + COMP_Y0;
/* we need sina and cosa to rotate compass arrow */
sina = (float)yh/xy_mean;
cosa = (float)xh/xy_mean;
}
ui_update(&evt); ui_update(&evt);
} }
......
...@@ -50,7 +50,7 @@ menu_list main_menu = { ...@@ -50,7 +50,7 @@ menu_list main_menu = {
"Main menu", "Main menu",
{ {
{ APP, &example_icon, { .app = &example } }, { APP, &example_icon, { .app = &example } },
{ APP, NULL, { .app = &compass } }, { APP, &comp_ico, { .app = &compass } },
{ SUBMENU, &settings_icon, { .submenu = &settings_menu } }, { SUBMENU, &settings_icon, { .submenu = &settings_menu } },
{ END, NULL, { NULL } } { END, NULL, { NULL } }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment