TentoBugのアイコン画像
TentoBug 2024年12月28日作成 (2025年01月27日更新)
セットアップや使用方法 セットアップや使用方法 Lチカ Lチカ 閲覧数 220
TentoBug 2024年12月28日作成 (2025年01月27日更新) セットアップや使用方法 セットアップや使用方法 Lチカ Lチカ 閲覧数 220

SPRESENSEでv=rω・・・。

はじめに

SPRESENSEに、どのような機能があるかを確認することを年末年始とコンテストの目標にしました。さわっているうちにGPIOやI2Cやパソコンのシリアルポートと通信ができることが分かりました。さらにGNSSを利用して位置情報の機能があることを知りました。なにか実験してみようと思って、教科書を眺めていますと

等速円運動の大きさ v=rωv =r \omega
加速度の大きさ   a=rω2a =r \omega^2
向心力       F=mv2rF =\frac{mv^2}{r}

が目に入り、

キャプションを入力できます
という具合に袋にSPRESENSEを入れて回すか、グルグル走るかしたら、なんか見えるのかなと思い図工しだしました。
 今のところI2Cを用いた表示とパソコンとの通信はできましたが、室内で速度vとωの確認で行き詰った感じです。その記録です。

部品

部品 備考(敬称略)
U1、U3 SPRESENSE
U2 MM-TXS01 サンハヤト
U4 AE-AQM0802 秋月電子通商
D1 LED(赤)
D2 LED(黄)
U5 RPR-220 ローム
減速機 タミヤ
安定化電源
USBケーブル ジャンク品
電池BOX

設計図

回路図
PIN_D16やPIN_D17にハイ電圧をかけることで、3種類のケースに分けます。

3Dプリンタで印刷する固定具

ソースコード

2024年 SPRESENSE™ 活用コンテストのチュートリアルにあるArduino IDEで作成しました。付属スケッチ例にあるgnssをを素にして作成しました。

実験中

#include <time.h> #include <FFT.h> #include <GNSS.h> #include <Wire.h>/* I2C*/ #include <Flash.h> #include <File.h> #define STRING_BUFFER_SIZE 128 /**< %Buffer size */ static SpGnss Gnss; /**< SpGnss object */ int duty=0; File FlashFile; uint64_t btime=0; unsigned long syuki=0; unsigned int warikomi(void){ digitalWrite(PIN_D22, HIGH); delayMicroseconds(duty); digitalWrite(PIN_D22, LOW); delayMicroseconds(500-duty); return 500; } unsigned int photosensor(void){ syuki=(unsigned long)(millis()-btime); btime=millis(); return 1; } void lcdClear(){ char command[]={0x38,0x01}; Wire.beginTransmission(0x3E); Wire.write(command,2); Wire.endTransmission(); delay(200); } void lcd1(char* StringBuffer){ Wire.beginTransmission(0x3E); Wire.write(0x00); Wire.write(0x80); Wire.endTransmission(); delay(1); Wire.beginTransmission(0x3E); Wire.write(0x40); Wire.write(StringBuffer,8); Wire.endTransmission(); delay(1); } void lcd2(char* StringBuffer){ Wire.beginTransmission(0x3E); Wire.write(0x00); Wire.write(0x80+0x40); Wire.endTransmission(); delay(1); Wire.beginTransmission(0x3E); Wire.write(0x40); Wire.write(StringBuffer,8); Wire.endTransmission(); delay(1); } void setup() { char StringBuffer[STRING_BUFFER_SIZE]; /* ポートの設定 */ pinMode(PIN_D02, OUTPUT); pinMode(PIN_D22, OUTPUT); pinMode(PIN_D23, OUTPUT); pinMode(PIN_D21, INPUT_PULLDOWN); pinMode(PIN_D16, INPUT_PULLDOWN); pinMode(PIN_D17, INPUT_PULLDOWN); /* シリアル通信設定 */ Serial.begin(115200); sleep(3); attachInterrupt(PIN_D21, photosensor, RISING); attachTimerInterrupt(warikomi,500);//us duty=0; syuki=0; /*LCDモジュール初期化*/ int i=0; char command[]={0x38,0x39,0x14,0x70,0x56,0x6C,0x38,0x0C,0x01}; digitalWrite(PIN_D02, LOW); delay(200); digitalWrite(PIN_D02, HIGH); Wire.begin(); delay(200); Wire.beginTransmission(0x3E); Wire.write(command,9); Wire.endTransmission(); delay(200); snprintf(StringBuffer, STRING_BUFFER_SIZE, "setup "); lcd1(StringBuffer); /* Set serial baudrate. */ Serial.begin(115200); /* Set Debug mode to Info */ Gnss.setDebugMode(PrintInfo); int result; /* Activate GNSS device */ result = Gnss.begin(); Gnss.select(GPS); Gnss.select(QZ_L1S); Gnss.select(QZ_L1CA); Gnss.setInterval(SpInterval_10Hz); /* Start positioning */ result = Gnss.start(COLD_START); } static void print_0(SpNavData *pNavData) { char StringBuffer[STRING_BUFFER_SIZE]; int e=0; struct tm now; /* 日本時間の設定 日付?*/ now.tm_year =pNavData->time.year; now.tm_mon =pNavData->time.month; now.tm_mday =pNavData->time.day; now.tm_hour =pNavData->time.hour+9; now.tm_min =pNavData->time.minute; now.tm_sec =pNavData->time.sec; //mktime(&now); snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d,%f,%3.3f,%d", now.tm_hour,// pNavData->time.minute, pNavData->time.sec, pNavData->direction, pNavData->velocity, //速さ duty ); Serial.print(StringBuffer); Serial.println(""); /* LCD2行目 */ snprintf(StringBuffer, STRING_BUFFER_SIZE, "%2d %5ld", pNavData->numSatellites, syuki); lcd2(StringBuffer); /* LCD1行目 */ snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d", now.tm_hour,// pNavData->time.minute, pNavData->time.sec); lcd1(StringBuffer); } static void print_1(SpNavData *pNavData) { char StringBuffer[STRING_BUFFER_SIZE]; int e=0; struct tm now; /* 日本時間の設定 日付?*/ now.tm_year =pNavData->time.year; now.tm_mon =pNavData->time.month; now.tm_mday =pNavData->time.day; now.tm_hour =pNavData->time.hour+9; now.tm_min =pNavData->time.minute; now.tm_sec =pNavData->time.sec; snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d %02d %2d", pNavData->time.minute, pNavData->time.sec, pNavData->numSatellites ); /* LCD1行目 */ lcd1(StringBuffer); if (pNavData->posDataExist == 1){ duty=250; snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d.%06ld,%6f,%6f,%3.3f,%3.3f,%3.3f,%d,%5ld", now.tm_hour,// pNavData->time.minute, pNavData->time.sec, pNavData->time.usec, pNavData->latitude, pNavData->longitude, pNavData->direction,//角度 pNavData->velocity, //速さ pNavData->altitude, pNavData->numSatellites,//衛星 syuki ); Serial.print(StringBuffer); Serial.println(""); //Flash.begin(); File f=Flash.open("shimako/data.csv",FILE_WRITE); f.println(StringBuffer); f.close(); /* LCD2行目 */ snprintf(StringBuffer, STRING_BUFFER_SIZE, "%2d %5ld", pNavData->numSatellites, syuki); lcd2(StringBuffer); }else{ duty=0; snprintf(StringBuffer, STRING_BUFFER_SIZE, "wait...."); lcd2(StringBuffer); } } /* ファイルの読み込んで送信 */ void r() { lcdClear(); lcd1("r "); FlashFile = Flash.open("shimako/data.csv"); if (FlashFile) { Serial.println("data.csv"); while (FlashFile.available()) { Serial.write(FlashFile.read()); } Serial.print("\r\n"); //受け側による。タイムアウト・・・。 FlashFile.close(); } else { /* ファイルがない時 */ Serial.println("error"); } } /* ? */ void d(){ lcdClear(); lcd1("d "); Serial.println("filepath"); String filepath; Flash.exists(filepath); Serial.println(filepath); } /* 初期化 */ void f(){ lcdClear(); lcd1("f "); Serial.println("format"); Flash.format(); Flash.mkdir("shimako/"); Serial.println("good"); } int ad=0; int hugo=1; SpNavData NavData; void loop() { int sw=digitalRead(PIN_D16)+2*digitalRead(PIN_D17); //メニュー switch (sw){ case 0: Gnss.getNavData(&NavData); print_0(&NavData); break; case 1: if(Gnss.isUpdate()==1){ Gnss.getNavData(&NavData); print_1(&NavData); } break; case 2: unsigned int SelialCom; //lcdClear(); lcd1("r f d "); lcd2(" "); SelialCom=Serial.read(); switch(SelialCom){ case 'r': r(); break; case 'f': f(); break; case 'd': d(); break; } break; } }

実験

  1. 3Dプリンタで固定具を印刷して、減速機などを固定します。減速機の六角棒は40mmに切断しました。反射センサーの目印として100mm x 20mmの紙片を置きます。

  2. 横棒の上にSPRESENSEなどを中心から15cm位の場所に固定します。
    正面
    だいぶ傾いています。印刷時に厚みとか調整したほうが良さそう。
    平面

  3. PIN_D16にハイ電圧、PIN_D17を浮かすはセーフ?(プルダウンの設定をしていたら?)

  4. 表示が変わったら減速機に任意に電圧をかけます。始動時は少し高めの電圧かけて、今回は0.25Vまで下げてみました。

データの整理

  1. PIN_D16にロー、PIN_D17をハイにします。

  2. パソコンでデータを吸い上げます。
    VS C#
    表計算で加工中の雰囲気

  3. 速さの分布図を作成してみました。
    分布図

  4. 時間のグラフを作成します。
    キャプションを入力できます

考察

  1. グラフや表を整理していくと。

r=0.15[m]r=0.15 [m]

ω=θ/t=2π/4.5=1.4\omega={\theta/t}=2\pi/4.5=1.4

rω=0.15×1.4=0.21r\omega=0.15{\times}1.4=0.21

  1. うーん。0m/sを消してみると。
    キャプションを入力できます
    キャプションを入力できます
  2. うーん。近いような。電圧変えてどうなるだろう。
    Gnss.setInterval(SpInterval_10Hz);を変えるとどうなるかな。
  3. 実験ではR7に3.3Vかけました。高さによったり黒い紙だと高い電圧がでるので検討が必要です。

参考

https://elchika.com/promotion/spresense2024/library/#nav
https://developer.sony.com/spresense/development-guides/arduino_developer_guide_ja.html#signalprocessing%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA

TentoBugのアイコン画像
テントウ虫も好きなのですが、違います。アマチュアとしてプログラムを書くので、バグや虫が10個以上はあります。誤記脱字も多いところからつけた名前です。回路やプログラムも怪しいのを掲載していて、動作を保証できませんがヨロシクお願いします。
ログインしてコメントを投稿する