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
const uint8_t *data;
};
extern const struct rle_bitmap gps_disconnected;
extern const struct rle_bitmap date_icon;
extern const struct rle_bitmap gps_receiving;
extern const struct rle_bitmap comp_circle;
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 gps_searching;
extern const struct rle_bitmap settings_icon;
extern const struct rle_bitmap compass_arrow;
extern const struct rle_bitmap comp_ico;
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 */
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 += \
-I../common/CMSIS/Include \
-I../common/Device/EnergyMicro/EFM32GG/Include \
-I../common \
-I../common/usb \
-I../common/usb/inc \
-I../common/emlib/inc \
-I../common/emdrv/sleep/inc \
......@@ -167,6 +169,14 @@ C_SRC += \
../common/gfx/graphics.c \
../common/gfx/gfx.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/tasks.c \
FreeRTOS/Source/queue.c \
......
......@@ -29,18 +29,55 @@
#include <drivers/LSM303C/lsm303c.h>
#include <bitmaps.h>
#include <sincos.h>
#include <usbdesc.h>
#define COMPASS_R 50
#define COMPASS_X0 64
#define COMPASS_Y0 64
#define COMP_R 50.0
#define COMP_X0 64
#define COMP_Y0 64
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 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_draw_bitmap(&w->dc, 64, 64, &compass_arrow);
gfx_line(&w->dc, COMPASS_X0, COMPASS_Y0, x_lcd, y_lcd, 1);
//gfx_line(&w->dc, COMP_X0, COMP_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)
......@@ -69,12 +106,15 @@ void compass_main(void *params)
(void)(params);
struct event evt;
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;
float xy_mean;
char buf[50];
/*lsm303 init, we need both ACC & MAG for tilt/roll compensation*/
lsm303_init();
USBD_Init(&initstruct);
ui_clear();
ui_init_widget(&compass_screen);
......@@ -97,32 +137,68 @@ void compass_main(void *params)
case BUTTON_PRESSED:
if(evt.data.button == BUT_TR)
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 {
lsm303_get_sample(DEV_ACC, &acc);
lsm303_get_sample(DEV_MAG, &mag);
/* calculate pitch and roll from accelerometer */
x2 = acc.x * acc.x;
y2 = acc.y * acc.y;
z2 = acc.z * acc.z;
pitch = -small_atan(acc.x, small_sqrt(acc.y*acc.y + acc.z*acc.z));
roll = small_atan(acc.y, small_sqrt(acc.x*acc.x + acc.z*acc.z));
/* work with compass readout, first revert it because magnetic south is north */
mag.x *= -1;
mag.y *= -1;
mag.z *= -1;
/*now calculate heading based on MAG readout and pinch/roll*/
xh = mag.x*small_cos(pitch) + mag.z*small_sin(pitch);
yh = mag.x*small_sin(roll)*small_sin(pitch) + mag.y*small_cos(roll) -
mag.z*small_sin(roll)*small_cos(pitch);
/* calculate x,y for compass in cartesian */
xy_mean = small_sqrt(xh*xh + yh*yh);
x_comp = COMPASS_R*yh / xy_mean;
y_comp = COMPASS_R*xh / xy_mean;
/* transform to LCD coordinates */
x_lcd = x_comp + COMPASS_X0;
y_lcd = -y_comp + COMPASS_Y0;
if(calib==1) {
/* we try to find min and max for axis to calibrate */
if(mag.x > c_max.x) c_max.x = mag.x;
if(mag.x < c_min.x) c_min.x = mag.x;
if(mag.y > c_max.y) c_max.y = mag.y;
if(mag.y < c_min.y) c_min.y = mag.y;
if(mag.z > c_max.z) c_max.z = mag.z;
if(mag.z < c_min.z) c_min.z = mag.z;
}
if(!calib) {
/* calculate pitch and roll from accelerometer */
x2 = acc.x * acc.x;
y2 = acc.y * acc.y;
z2 = acc.z * acc.z;
pitch = -small_atan(acc.x, small_sqrt(acc.y*acc.y + acc.z*acc.z));
roll = small_atan(acc.y, small_sqrt(acc.x*acc.x + acc.z*acc.z));
sprintf(buf, "p: %d, r: %d\n\r", pitch, roll);
USBD_Write(USBDESC_EP_DATA_OUT, (void*)buf, strlen(buf), NULL);
/* work with compass readout, first revert it because magnetic south is north */
mag.x *= -1;
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);
}
......
......@@ -50,7 +50,7 @@ menu_list main_menu = {
"Main menu",
{
{ APP, &example_icon, { .app = &example } },
{ APP, NULL, { .app = &compass } },
{ APP, &comp_ico, { .app = &compass } },
{ SUBMENU, &settings_icon, { .submenu = &settings_menu } },
{ 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