Spresense ソースコードその1(メイン(設定部分))

※2020年10月13日修正(設定温度改良に伴う)

某ブラウザゲームのイベントとかやっていて間が空いてしまいましたが、ソースコードです。開発環境は主流ではないですがSpresense SDKを使用しています。理由は拡張性が高そうに見えたことと、Arduino IDE環境だとチャタリング防止機構を無効にできず使用している温度センサーが上手く使えなかったためです。ただ、主流ではないだけに資料があまりにも少なくLチカまではそこそこできたものの、その先はほぼ完全に手探り。結局モニター用の液晶は最後まで表示できませんでした。一方で、SDK環境で用いるNuttx OSはマルチスレッドに対応しておりSpresenseのマルチコアCPUと合わせて拡張性の高さの片鱗を見ることもできました。

能書きは終わりにして、まずはメインの部分から。ここに肝心な部分はあまりありませんが、マルチスレッドの設定や各プログラムの呼び出しなんかをやっています。

#include <sdk/config.h>
#include <stdio.h>
#include <arch/board/board.h>
#include <arch/chip/pin.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <arch/chip/gnss.h>

//各プログラム呼び出し用ヘッダ//
#include "heattemp.h"
#include "watemp.h"
#include "gnssclk.h"
#include "cntunit.h"
#include "ledout.h"

//測定、更新間隔設定//
int intvlh = 1; //ヒーター測定、判定間隔(秒単位)
int intvla = 3; //水温、気温判定間隔(秒単位)
int sintv = 2; //水温、気温測定間隔(秒単位、2秒以上)
int shour = 60, sday = 24, sweek = 7; //各時間間隔ごとの気温計測数

//温度範囲設定(12ヶ月分+1番目は時刻未取得時の値)//
//月別ヒーター温度上限(ここを越えたら絶対に止める)//
float vtemp_hmax[13] = { 7, 10, 10, 12, 20, 25, 25, 25, 25, 25, 20, 15, 12}; 

//月別ヒーター温度下限(ここを下回ったら絶対に動かす)//
float vtemp_hmin[13] = { 3, 5, 5, 8, 15, 20, 20, 20, 20, 20, 15, 10, 6};
 
//月別ファン制御温度上限(ここを越えたら絶対に動かす)//
float vtemp_wmax[13] = { 25, 15, 15, 20, 25, 26, 26, 26, 26, 26, 24, 20, 18}; 

//月別ファン制御温度下限(ここを下回ったら絶対に止める)//
float vtemp_wmin[13] = { 18, 10, 10, 15, 18, 20, 20, 20, 20, 20, 18, 15, 12}; 

//月別水凍結防止ヒーター温度上限(ここを越えたら絶対に止める)//
float vtemp_h2max[13] = { 5, 7, 7, 10, 15, 15, 18, 18, 18, 15, 15, 10, 7}; 

//月別水凍結防止ヒーター温度上限(ここを下回ったら絶対に動かす)//
float vtemp_h2min[13] = { 2, 2, 2, 5, 10, 15, 15, 15, 15, 15, 10, 3, 2}; 


//温度設定用係数(0〜10で設定。数字が大きいほど温度が高めになる。
//ヒーターとクーラーの設定次第で両方動作する場合がある)

//ヒーターの月別係数設定。
//冬季は冬眠の邪魔をしないように低め、夏季は高めに設定
float ntemp_heat[13] = { 3, 2, 2, 3, 4, 4, 5, 5, 5, 4, 3, 3, 2};

//クーラーの月別係数設定。
//梅雨寒等を想定して6月は高め、猛暑な7〜9月は曝気目的もあって低め
float ntemp_cool[13] = { 7, 5, 5, 6, 7, 7, 7, 6, 6, 6, 6, 5, 5};
//フラグ、変数類// int emstp = 0; //非常停止フラグ int hold_flg = 0; //一時停止フラグ int heat_flg = 0; //ヒーター動作 int cool_flg = 0; //ファン動作 int wthr_flg = 0; //追加ヒーター動作 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // プログラム本体 // #ifdef CONFIG_BUILD_KERNEL int main(int argc, FAR char *argv[]) #else int wtcont_main(int argc, char *argv[]) #endif { //とりあえずLEDの端子属性を指定して全部消灯// board_gpio_config(PIN_I2S1_BCK, 0, false, true, 0); //LED0 board_gpio_config(PIN_I2S1_LRCK, 0, false, true, 0); //LED1 board_gpio_config(PIN_I2S1_DATA_IN, 0, false, true, 0); //LED2 board_gpio_config(PIN_I2S1_DATA_OUT, 0, false, true, 0); //LED3 usleep(200*1000); //LED点滅して起動表示// board_gpio_write(PIN_I2S1_BCK, 1); board_gpio_write(PIN_I2S1_LRCK, 1); board_gpio_write(PIN_I2S1_DATA_IN, 1); board_gpio_write(PIN_I2S1_DATA_OUT, 1); usleep(500*1000); board_gpio_write(PIN_I2S1_BCK, 0); board_gpio_write(PIN_I2S1_LRCK, 0); board_gpio_write(PIN_I2S1_DATA_IN, 0); board_gpio_write(PIN_I2S1_DATA_OUT, 0); usleep(10*1000); //マルチスレッド設定+各プログラム呼び出し//
//スレッド数はコア数(6個)以内にするのが吉っぽい// pthread_t thread_A, thread_B, thread_C, thread_D, thread_E; pthread_create(&thread_A, NULL, heattemp, NULL); pthread_create(&thread_B, NULL, watemp, NULL); pthread_create(&thread_C, NULL, cntunit, NULL); pthread_create(&thread_D, NULL, gnssclk, NULL); pthread_create(&thread_E, NULL, ledout, NULL); pthread_join(thread_A, NULL); pthread_join(thread_B, NULL); pthread_join(thread_C, NULL); pthread_join(thread_D, NULL); pthread_join(thread_E, NULL); usleep(200*1000); //異常終了時LED全部点灯// board_gpio_write(PIN_I2S1_BCK, 1); board_gpio_write(PIN_I2S1_LRCK, 1); board_gpio_write(PIN_I2S1_DATA_IN, 1); board_gpio_write(PIN_I2S1_DATA_OUT, 1); return 0; }

使った資料はSpresense公式ページとどこかは失念しましたがブログサイト様、Nuttx OSを扱ったページいくつかです。マイコンを扱うというのが頭に強くこびりついていて最初苦労しましたが、OSを介して動かすことからPCの扱いに近い部分があることに気づくと幾らか楽になりました。接続するデバイスはドライバが見つかればかなり簡単に扱えるようです。

マルチスレッド対応ですが、スレッド数はコア数以内で抑えないとリアルタイム制御が上手くいかなくなるようです。当初、停止ボタンの動作管理も別スレッドで記述していましたが、センサーの動作時間制御が不安定になり温度をまともに検出できなくなったので各プログラムに潜り込ませて対応しました。停止ボタン押下検出の間隔を変化させても問題が解決せず、スレッド数をコア数以内で収めることで動作が安定しました。

This entry was posted in プログラミング, ベランダビオトープ, 園芸, 睡蓮水槽管理装置, 電子工作 and tagged , . Bookmark the permalink.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA