Open3
SONY Spresense VSCode Sample
SONY Spresense のHello World(VSCode版) サンプル
SpresenseのVSCodeでのサンプルコードが少なかったので、ちょっとづつ自分で試していこうと思います。
まずはお約束のHello Worldから始めましょう。
myapps_main.c
#include <sdk/config.h>
#include <stdio.h>
int myapps_main(int argc, char *argv[])
{
printf("Hello Spresense\n");
return 0;
}
SONY SpresenseのLED制御(Lチカ)サンプル
SpresenseのメインボードにはLEDが4つあり、ピン番号はそれぞれ 97
, 98
, 99
, 100
となっている。
led_main.c
#include <sdk/config.h>
#include <stdio.h>
#include <arch/board/board.h>
#include <arch/board/board_pinconfig.h>
int led_main(int argc, char *argv[])
{
int array[] = {97, 98, 99, 100};
for (int pin = 97; pin < 101; ++pin)
{
//board_gpio_config(/*ピン番号*/, /*モード*/, /*入力ピン:true*/, /*ドライブ電流大:true*/, /*プルアップ/ダウン設定*/);
board_gpio_config(pin, 0, false, true, 0);
}
while (true)
{
for (int pin = 97; pin < 101; ++pin)
{
board_gpio_write(pin, 1); //点灯
usleep(500 * 1000);
board_gpio_write(pin, 0); //消灯
}
}
return 0;
}
SONY Spresenseで位置情報取得サンプル
各国の衛星は各国の測位衛星を参照。
GNSSまわりの定数はここにある。
注意事項として
- 屋内では、たとえ窓際であっても衛星電波を捕まえるのは難しい。
- 屋外に出て実行すると数分で位置を取得できる。
- VSCodeでは
Spresense:SDKコンフィグ
でGNSS device (CXD56_GNSS)
を有効にしてから設定保存してコンパイル。
gps_main.c
/****************************************************************************
* Included Files
****************************************************************************/
#include <sdk/config.h>
#include <stdio.h>
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <arch/chip/gnss.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MY_GNSS_SIG 18
/****************************************************************************
* Private Types
****************************************************************************/
struct cxd56_gnss_dms_s
{
int8_t sign;
uint8_t degree;
uint8_t minute;
uint32_t frac;
};
/****************************************************************************
* Private Data
****************************************************************************/
static uint32_t posfixflag;
static struct cxd56_gnss_positiondata_s posdat;
/****************************************************************************
* Private Functions
****************************************************************************/
static int gnss_setparams(int fd)
{
int ret = 0;
uint32_t set_satelite;
struct cxd56_gnss_ope_mode_param_s set_opemode;
set_opemode.mode = 1; /* Operation mode:Normal */
set_opemode.cycle = 1000; /* Position notify cycle(msec) */
ret = ioctl(fd, CXD56_GNSS_IOCTL_SET_OPE_MODE, (uint32_t)&set_opemode);
if (ret < 0)
{
printf("CXD56_GNSS_IOCTL_SET_OPE_MODE failed!\n");
goto _err;
}
/* 日本:みちびき アメリカ:GPS ロシア:GLONASS */
set_satelite = CXD56_GNSS_SAT_QZ_L1S | CXD56_GNSS_SAT_GPS | CXD56_GNSS_SAT_GLONASS;
ret = ioctl(fd, CXD56_GNSS_IOCTL_SELECT_SATELLITE_SYSTEM, set_satelite);
if (ret < 0)
{
printf("CXD56_GNSS_IOCTL_SELECT_SATELLITE_SYSTEM failed!\n");
goto _err;
}
printf("Parameter Setting OK.\n");
_err:
return ret;
}
static void double_to_dmf(double x, struct cxd56_gnss_dms_s *dmf)
{
int b;
int d;
int m;
double f;
double t;
if (x < 0)
{
b = 1;
x = -x;
}
else
{
b = 0;
}
d = (int)x;
t = (x - d) * 60;
m = (int)t;
f = (t - m) * 10000;
dmf->sign = b;
dmf->degree = d;
dmf->minute = m;
dmf->frac = f;
}
/* 位置情報を取得して標準出力に表示する */
static int read_and_print(int fd)
{
int ret = 0;
struct cxd56_gnss_dms_s dmf;
ret = read(fd, &posdat, sizeof(posdat));
if (ret < 0)
{
printf("read gnss failed.\n");
goto _err;
}
else if (ret != sizeof(posdat))
{
ret = ERROR;
printf("read gnss size error;\n");
goto _err;
}
else
{
ret = OK;
}
printf("UTC Time %d:%d:%d, usec:%ld\n",
posdat.receiver.time.hour,
posdat.receiver.time.minute,
posdat.receiver.time.sec,
posdat.receiver.time.usec);
if (posdat.receiver.pos_fixmode != CXD56_GNSS_PVT_POSFIX_INVALID)
{
posfixflag = 1;
double_to_dmf(posdat.receiver.latitude, &dmf);
printf("latitude: %d.%d.%04ld\n", dmf.degree, dmf.minute, dmf.frac);
double_to_dmf(posdat.receiver.longitude, &dmf);
printf("longitude: %d.%d.%04ld\n", dmf.degree, dmf.minute, dmf.frac);
}
else
{
printf("No positioning Data.\n");
}
_err:
return ret;
}
/* メイン関数 */
int gps_main(int argc, char *argv[])
{
int ret;
int fd;
sigset_t mask;
struct cxd56_gnss_signal_setting_s setting;
printf("Hello GPS\n");
fd = open("/dev/gps", O_RDONLY);
if (fd < 0)
{
printf("device file open error:%d,%d\n", fd, errno);
return -ENODEV;
}
/* Configure mask to notify */
sigemptyset(&mask);
sigaddset(&mask, MY_GNSS_SIG);
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
if (ret != OK)
{
printf("sigprocmask failed%d\n", ret);
goto _err;
}
/* Set the signal to notify GNSS events */
setting.fd = fd;
setting.enable = 1;
setting.gnsssig = CXD56_GNSS_SIG_GNSS;
setting.signo = MY_GNSS_SIG;
setting.data = NULL;
ret = ioctl(fd, CXD56_GNSS_IOCTL_SIGNAL_SET, (unsigned long)&setting);
if (ret < 0)
{
printf("signal error\n");
goto _err;
}
/* Set GNSS parameter */
ret = gnss_setparams(fd);
if (ret != OK)
{
printf("Set GNSS parameter failed.\n");
goto _err;
}
/* Start GNSS */
int posperiod = 200;
posfixflag = 0;
ret = ioctl(fd, CXD56_GNSS_IOCTL_START, CXD56_GNSS_STMOD_HOT);
if (ret < 0)
{
printf("start GNSS failed.\n");
goto _err;
}
else
{
printf("start GNSS ok.\n");
}
do
{
ret = sigwaitinfo(&mask, NULL);
if (ret != MY_GNSS_SIG)
{
printf("sigwaitinfo failed.\n");
break;
}
ret = read_and_print(fd);
if (ret < 0)
{
break;
}
if (posfixflag)
{
posperiod--;
}
} while (posperiod > 0);
ret = ioctl(fd, CXD56_GNSS_IOCTL_STOP, 0);
if (ret < 0)
{
printf("stop GNSS failed.\n");
}
else
{
printf("stop GNSS OK.\n");
}
_err:
setting.enable = 0;
ret = ioctl(fd, CXD56_GNSS_IOCTL_SIGNAL_SET, (unsigned long)&setting);
if (ret < 0)
{
printf("signal error\n");
}
sigprocmask(SIG_UNBLOCK, &mask, NULL);
ret = close(fd);
if (ret < 0)
{
printf("Device file close failed.\n");
}
printf("Finish.\n");
return 0;
}
ちなみに蛇足だけど、僕がはじめてSpresenseで位置情報を取得した本日は、奇しくも「みちびき」の打ち上げに成功した日だった。もしかして今日打ち上げられた「みちびき」から位置情報を受け取ってるかもしれないと思うとロマンですな。