./Positioning1 GPS by Spresense
■IDEツールのダウンロード
下記サイトより、ダウンロードする。2016/9/20現在
・''Arduino"
Arduino usa
からDownloadのタブにて、下記サイトからOSにあったInstallerを選択。
・''Arduino download site"
切り替わったSiteから"Just Download"をクリックすると、ダウンロードが始まります。
ファイル名:arduino-1.6.11-windows.exe
これを実行し、基本的は"Yes"を選択していってください。
再度のウィンドウで、"Close"をクリックするとインストールは完了です。
さて次にハードをUSBケーブルで接続してみましょう。
うまくいくと、PCで認識し、デバイスマネージャーでみることができます。
このときCOM5でに認識しているのがわかります。
それでは、Arduinoを起動します。Programfilesの中にある、"Arduino"をクリックしますと下記ウィンドウが表示されます。
ここで、"ツール"→シリアルポートCOMnと辿り、先ほどに錦しているポートを選択してください。
また同じく”ツール”→ボード***から正しいボードを選択します。
ここではArduino/Genuino Unoを選択します。(下記絵図)
セットアップはこれで完了です。
■1.LED blink
今度は実際にマイコンを動かします。
・ハードウェアセットアップ
13pinとGNDに、LEDを取り付けます。(リードを指すだけですが、13ピンがアノード、GNDにカソードです。)
これだけです。
・ソフトウェアセットアップ
下記プログラムを入力します。
const int LED = 13; //LED connected to digital pin 13 ----- LEDに13を代入 intなので、整数、constは、プログラム中に変更がない定数を意味する。 void setup() ---- この{}内をブロックという、setup()は必ず1回だけ実行される。 { pinMode(LED,OUTPUT); //sets the digital ----ピンモード関数でピン状態を設定する。13pin(LEDと名前がついた)をデジタル出力と設定する。 //pin as output } void loop() ----この{}内をブロックという。loop()は繰り返し実行される。 { digitalWrite(LED,HIGH); //turns the LED on ---digitalWrite関数は、2つの引数。最初の引数LEDはピン指定。次の引数HIGHは状態を指定。このときはHIgh delay(1000); //waits for a second ---delay関数はもじ通り遅延時間を与える。引数はmsec。 digitalWrite(LED,LOW); //turns the LED off ---digitalWrite関数。今度はLowとする。 delay(1000); //waits for a second ---既出 }
■2.LED SW
今度はSWを入力として、動作を変化させるプログラムです。
・ハードウェアセットアップ
13pinとGNDに、LEDを取り付けます。(リードを指すだけですが、13ピンがアノード、GNDにカソードです。)
7pin ---プルダウン抵抗1kをGNDへ接続
7ipn ---SW片側を接続、SWの逆側端子---5Vへ接続
下記写真の通りです。実体と回路構成を示します。
・ソフトウェアセットアップ
//Example 02 : SW入力によるLED点灯 const int LED = 13; //LED connected to 13pin const int BUTTON =7; //push botton to 7 int val = 0 ; //入力ピンの状態がこの変数に記憶 void setup(){ pinMode(LED,OUTPUT); //sets LET to OUTPUT pinMode(BUTTON,INPUT); //buttonは入力に設定 } void loop(){ val = digitalRead(BUTTON); //入力を読み取り、valに格納 if(val == HIGH){ digitalWrite(LED,HIGH); //turns the LED on }else{ digitalWrite(LED,LOW); //turns the LED off } }
押した状態を保持する場合は下記のようにします。
ハードウェアは 同じです。
入力値(新値)をval ,旧値はold_val です。~この2つに差異があり、新値が1の場合は点灯statusを1として点灯します。 新値が0の場合は消灯です。
//Example 02-2 : SW入力によるLED点灯(押した状態保持)
const int LED = 13; //LED connected to 13pin const int BUTTON =7; //push botton to 7 int val = 0 ; //入力ピンの状態がこの変数に記憶 int old_val = 0 ; //valの前回値 int state = 0 ; //LEDを点灯させる直接の変数 1ならオン、0ならオフ void setup(){ pinMode(LED,OUTPUT); //sets LET to OUTPUT pinMode(BUTTON,INPUT); //buttonは入力に設定 } void loop(){ val = digitalRead(BUTTON); //入力を読み取り、valに格納 if((val == HIGH)&&(old_val == LOW)){ //valがHIGH且つold_valがLOWのとき、&&は論理AND state = 1- state; delay(100); } old_val = val ; // if(state == 1){ digitalWrite(LED,HIGH); //turns the LED on }else{ digitalWrite(LED,LOW); //turns the LED off } }
■4.RTC I2C
次にRTCをI2CのI/Fにて制御する方法を実験します。
・ハードウェアセットアップ
RTCモジュールをArduinoの外付けとします。
ここではDS1307のモジュールを使用しますが、接続が合えば単品でも構いません。
ここではサインスマート製Tiny RTC I2C DS1307 AT24C32 24C32 メモリ リアルタイムクロックモジュール for Arduinoを使用します。
・ソフトウェアセットアップ
(1)まず動作確認用のスケッチを作成します。下記のとおりです。
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> const int DS1307_ADDRESS=0x68;int val=0; byte sec,minute,hour,day,week,month,year,ctrlb; void setup(){ Wire.begin(); Serial.begin(2400); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.write(val); Wire.endTransmission(); } void loop () { Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,8); sec=Wire.read(); minute=Wire.read(); hour=Wire.read(); week=Wire.read(); day=Wire.read(); month=Wire.read(); year=Wire.read(); ctrlb=Wire.read();
Serial.print("sec="); Serial.println(sec,HEX); Serial.print("minute="); Serial.println(minute,HEX); Serial.print("hour="); Serial.println(hour,HEX); Serial.print("week="); Serial.println(week,HEX); Serial.print("day="); Serial.println(day,HEX); Serial.print("month="); Serial.println(month,HEX); Serial.print("year="); Serial.println(year,HEX); Serial.print("ctrlb="); Serial.println(ctrlb,HEX); delay(2800); }
検証コンパイル後、Arduinoに書き込みます。その後、IDEの"ツール"メニューから→シリアルモニタをクリックします。 下記画面でシリアル通信にて取得したRTCの内部レジスタの時刻を確認できます。
■4-2.RTC I2C
次に同じハードウェア構成で、時刻設定をシリアルから行い、それをシリアルで受信するようにプログラムを改変します。
・ソフトウェアセットアップ
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> const int DS1307_ADDRESS=0x68;int val=0; byte command; void setup(){ Serial.begin(2400); Wire.begin(); Serial.flush(); } void loop () { if(Serial.available()){ command=Serial.read(); if(command==0x74){ //"t"=0x74 setTime(); } Serial.println(command); if(command==0x64){ //"d"=0x64 setDay(); } } printTime(); delay(2000); } void setTime(){ byte hour=(Serial.read()<<4); hour=hour+(Serial.read() & 0x0F); byte minute=(Serial.read()<<4); minute=minute+(Serial.read() & 0x0F); byte sec=(Serial.read()<<4); sec=sec+(Serial.read() & 0x0F); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.write(sec); Wire.write(minute); Wire.write(hour); Wire.endTransmission(); } void setDay(){ byte year=(Serial.read() <<4); year=year+(Serial.read() & 0x0F); byte month=(Serial.read() <<4); month=month+(Serial.read() & 0x0F); byte day=(Serial.read() <<4); day=day+(Serial.read() & 0x0F); byte day_of_week=(Serial.read() & 0x07); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0x03); Wire.write(day_of_week); Wire.write(day); Wire.write(month); Wire.write(year); Wire.endTransmission(); } void printTime(){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,7); byte r_sec=Wire.read(); byte r_minute=Wire.read(); byte r_hour=Wire.read(); byte r_day_of_week=Wire.read(); byte r_date=Wire.read(); byte r_month=Wire.read(); byte r_year=Wire.read(); Serial.print(r_year,HEX); Serial.print("/"); Serial.print(r_month,HEX); Serial.print("/"); Serial.print(r_date,HEX); Serial.print(" "); Serial.print(r_hour,HEX); Serial.print(":"); Serial.print(r_minute,HEX); Serial.print(":"); Serial.print(r_sec,HEX); Serial.print(" smtwtfs= "); Serial.println(r_day_of_week,HEX); }
■5.SD SPI
SDカードアクセスの仕方を学びます。基本的にはSPIモードでのアクセスです。
・ハードウェアセットアップ
写真省略。
回路図は下記の通りです。
#include <SD.h>
// CS信号は今回4とします。 const int chipSelect = 4; void setup() { // シリアルポート初期化 Serial.begin(9600); } Serial.print(F("Initializing SD card...")); // SSピン(Unoは10番、Megaは53番)は使わない場合でも出力にする必要があります。 // そうしないと、SPIがスレーブモードに移行し、SDライブラリが動作しなくなります。 pinMode(SS, OUTPUT); // SDライブラリを初期化 if (!SD.begin(chipSelect)) { Serial.println(F("Card failed, or not present")); // 失敗、何もしない while(1); } Serial.println(F("ok.")); // 日付と時刻を返す関数を登録 SdFile::dateTimeCallback( &dateTime ); } void loop() { // ファイルを開く File dataFile = SD.open("datalog.txt", FILE_WRITE); // もしファイルが開けたら値を書き込む if (dataFile) { int value = analogRead(0); dataFile.println(value); dataFile.close(); // シリアルポートにも出力 Serial.println(value); } // ファイルが開けなかったらエラーを出力 else { Serial.println(F("error opening datalog.txt")); } // 一秒待つ delay(1000); } void dateTime(uint16_t* date, uint16_t* time) { uint16_t year = 2013; uint8_t month = 2, day = 3, hour = 9, minute = 0, second = 0; // GPSやRTCから日付と時間を取得 // FAT_DATEマクロでフィールドを埋めて日付を返す *date = FAT_DATE(year, month, day); // FAT_TIMEマクロでフィールドを埋めて時間を返す *time = FAT_TIME(hour, minute, second); }
■6.RTC_SD
ある入力ポートのデジタル値が変化したときの、RTCの値をSDカードに記録するデバイスを作成します。
前述の4-2RTCと5SD_SPIの結合で実現します。
・ハードウェアセットアップ
下記の通りです。digital7ピンは便宜上SWを接続し、Highレベルの検知を行います。ここが観測対象のデバイスからのトリガ入力となります。
あとはRTC,SDの結合です。
・ソフトウェアセットアップ
#include <SD.h> //SDのライブラリ使用 #include <Wire.h> //Wire(I2C)のライブラリ使用 const int DS1307_ADDRESS=0x68;int val=0; //I2Cのアドレス選択 const int BUTTON =7; //push botton to 7 デジタル入力トリガ用 byte command; //command 定義 シリアルにて時刻設定コマンド int valb = 0 ; //入力ピンの状態がこの変数に記憶 int valb_old = 0 ;//入力前回値 int status = 1 ;//ステータス
// SUNFOUNDER製のCSも4ピンに設定します。 const int chipSelect = 4; void setup() { pinMode(BUTTON,INPUT); //buttonは入力に設定 // シリアルポート初期化 Serial.begin(9600); //I2C初期化 Wire.begin(); Serial.flush(); }
Serial.print(F("Initializing SD card...")); // SSピン(Unoは10番、Megaは53番)は使わない場合でも出力にする必要があります。 // そうしないと、SPIがスレーブモードに移行し、SDライブラリが動作しなくなります。 pinMode(SS, OUTPUT); // SDライブラリを初期化 if (!SD.begin(chipSelect)) { Serial.println(F("Card failed, or not present")); // 失敗、何もしない while(1); } Serial.println(F("ok.")); } void loop() { valb = digitalRead(BUTTON); //入力を読み取り、valbに格納 // ファイルを開く if((valb == HIGH)&&(valb_old == LOW)) {File dataFile = SD.open("datalog.txt", FILE_WRITE); status = 1 ; //statusが1だったらファイル書き込みを行う。 if(status == 1); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,7); byte r_sec=Wire.read(); byte r_minute=Wire.read(); byte r_hour=Wire.read(); byte r_day_of_week=Wire.read(); byte r_date=Wire.read(); byte r_month=Wire.read(); byte r_year=Wire.read(); dataFile.print(r_year,HEX); dataFile.print("/"); dataFile.print(r_month,HEX); dataFile.print("/"); dataFile.print(r_date,HEX); dataFile.print(" "); dataFile.print(r_hour,HEX); dataFile.print(":"); dataFile.print(r_minute,HEX); dataFile.print(":"); dataFile.print(r_sec,HEX); dataFile.print(" smtwtfs= "); dataFile.println(r_day_of_week,HEX); dataFile.close(); // シリアルポートにも出力 printTime(); //関数呼び出し。自作関数 loop()の後ろに記述 } // ファイルが開けなかったらエラーを出力なのだが、とりあえずログがうるさくなるのでコメントアウト else { // Serial.println(F("error opening datalog.txt")); } delay(100);// 0.1秒のラッチ時間 status = 0 ; //結局0にする。 Arduino内部では100msecのHIGH入力としたいため。 // 0.1秒待つ。チャタ防止 delay(100); //時刻設定 if(Serial.available()){ command=Serial.read(); if(command==0x74){ //"t"=0x74 setTime(); } Serial.println(command); if(command==0x64){ //"d"=0x64 setDay(); printTime(); delay(2000); } } }
//setTime,setDay,printTimeの関数記述。 void setTime(){ byte hour=(Serial.read()<<4); hour=hour+(Serial.read() & 0x0F); byte minute=(Serial.read()<<4); minute=minute+(Serial.read() & 0x0F); byte sec=(Serial.read()<<4); sec=sec+(Serial.read() & 0x0F); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.write(sec); Wire.write(minute); Wire.write(hour); Wire.endTransmission(); } void setDay(){ byte year=(Serial.read() <<4); year=year+(Serial.read() & 0x0F); byte month=(Serial.read() <<4); month=month+(Serial.read() & 0x0F); byte day=(Serial.read() <<4); day=day+(Serial.read() & 0x0F); byte day_of_week=(Serial.read() & 0x07); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0x03); Wire.write(day_of_week); Wire.write(day); Wire.write(month); Wire.write(year); Wire.endTransmission(); } void printTime(){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,7); byte r_sec=Wire.read(); byte r_minute=Wire.read(); byte r_hour=Wire.read(); byte r_day_of_week=Wire.read(); byte r_date=Wire.read(); byte r_month=Wire.read(); byte r_year=Wire.read(); Serial.print(r_year,HEX); Serial.print("/"); Serial.print(r_month,HEX); Serial.print("/"); Serial.print(r_date,HEX); Serial.print(" "); Serial.print(r_hour,HEX); Serial.print(":"); Serial.print(r_minute,HEX); Serial.print(":"); Serial.print(r_sec,HEX); Serial.print(" smtwtfs= "); Serial.println(r_day_of_week,HEX); }
■7.RTC_SD_NANO
ある入力ポートのデジタル値が変化したときの、RTCの値をSDカードに記録するデバイスを作成します。
6.RTC_SDをArduinoNano?用に修正します。
とはいってもポートは全て一緒ですので、同じピン名のコネクタにつなげ帰るだけでOKです。
・ハードウェアセットアップ
下記の通りです。digital7ピンは便宜上SWを接続し、Highレベルの検知を行います。ここが観測対象のデバイスからのトリガ入力となります。
回路図は、6,rtc_sdと同じです。
・ソフトウェアセットアップ
#include <SD.h> //SDのライブラリ使用 #include <Wire.h> //Wire(I2C)のライブラリ使用 const int DS1307_ADDRESS=0x68;int val=0; //I2Cのアドレス選択 const int BUTTON =7; //push botton to 7 byte command; //command 定義 int valb = 0 ; //入力ピンの状態がこの変数に記憶 int valb_old = 0 ;//入力前回値 int status = 1 ;//ステータス // イーサーネットシールドは 4 サウンドワンダー製のCSもこれで可能 const int chipSelect = 4; void setup() { pinMode(BUTTON,INPUT); //buttonは入力に設定 // シリアルポート初期化 Serial.begin(9600); //I2C初期化 Wire.begin(); Serial.flush(); while (!Serial) { ; // USBケーブルが接続されるのを待つ。この待ちループは Leonardo のみ必要。 } Serial.print(F("Initializing SD card...")); // SSピン(Unoは10番、Megaは53番)は使わない場合でも出力にする必要があります。 // そうしないと、SPIがスレーブモードに移行し、SDライブラリが動作しなくなります。 pinMode(SS, OUTPUT); // SDライブラリを初期化 if (!SD.begin(chipSelect)) { Serial.println(F("Card failed, or not present")); // 失敗、何もしない while(1); } Serial.println(F("ok.")); } void loop() { valb = digitalRead(BUTTON); //入力を読み取り、valbに格納 // ファイルを開く if((valb == HIGH)&&(valb_old == LOW)) {File dataFile = SD.open("datalog.txt", FILE_WRITE); status = 1 ; // もしファイルが開けたら値を書き込む if(status == 1); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,7); byte r_sec=Wire.read(); byte r_minute=Wire.read(); byte r_hour=Wire.read(); byte r_day_of_week=Wire.read(); byte r_date=Wire.read(); byte r_month=Wire.read(); byte r_year=Wire.read(); dataFile.print(r_year,HEX); dataFile.print("/"); dataFile.print(r_month,HEX); dataFile.print("/"); dataFile.print(r_date,HEX); dataFile.print(" "); dataFile.print(r_hour,HEX); dataFile.print(":"); dataFile.print(r_minute,HEX); dataFile.print(":"); dataFile.print(r_sec,HEX); dataFile.print(" smtwtfs= "); dataFile.println(r_day_of_week,HEX); dataFile.close(); // シリアルポートにも出力 printTime(); } // ファイルが開けなかったらエラーを出力 else { // Serial.println(F("error opening datalog.txt")); } delay(200); status = 0 ; // 0.01秒待つ delay(20); if(Serial.available()){ command=Serial.read(); if(command==0x74){ //"t"=0x74 setTime(); } Serial.println(command); if(command==0x64){ //"d"=0x64 setDay(); printTime(); delay(100); } } } void setTime(){ byte hour=(Serial.read()<<4); hour=hour+(Serial.read() & 0x0F); byte minute=(Serial.read()<<4); minute=minute+(Serial.read() & 0x0F); byte sec=(Serial.read()<<4); sec=sec+(Serial.read() & 0x0F); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.write(sec); Wire.write(minute); Wire.write(hour); Wire.endTransmission(); } void setDay(){ byte year=(Serial.read() <<4); year=year+(Serial.read() & 0x0F); byte month=(Serial.read() <<4); month=month+(Serial.read() & 0x0F); byte day=(Serial.read() <<4); day=day+(Serial.read() & 0x0F); byte day_of_week=(Serial.read() & 0x07); Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0x03); Wire.write(day_of_week); Wire.write(day); Wire.write(month); Wire.write(year); Wire.endTransmission(); } void printTime(){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(val); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS,7); byte r_sec=Wire.read(); byte r_minute=Wire.read(); byte r_hour=Wire.read(); byte r_day_of_week=Wire.read(); byte r_date=Wire.read(); byte r_month=Wire.read(); byte r_year=Wire.read(); Serial.print(r_year,HEX); Serial.print("/"); Serial.print(r_month,HEX); Serial.print("/"); Serial.print(r_date,HEX); Serial.print(" "); Serial.print(r_hour,HEX); Serial.print(":"); Serial.print(r_minute,HEX); Serial.print(":"); Serial.print(r_sec,HEX); Serial.print(" smtwtfs= "); Serial.println(r_day_of_week,HEX); }