2014年3月4日火曜日

AVRの16ビットタイマで時間の計測

AVRのマイコンにはたいてい、8ビットタイマーと16ビットタイマーの2つが用意されています。
私の場合、8ビットタイマーはPWMに使って、16ビットタイマーは時間の測定に使うことが多いです。

その、16ビットタイマーで時間の測定をするメモです。

時間の測定ということは、あるタイミングでカウンタをカウントしていくわけですが、16ビットタイマーでは当然16ビット分しかカウントできません。
カウントするタイミングは、最大1024分周、つまり1024クロックごとに1カウントという設定ができますから、
最大で計れる時間は、例えばクロックが16MHZの場合、

65535 * 1024 / 16,000,000 = 4.19424(秒)

4秒程度しか計れません。これではとても役に立たない。

それではどうするかというと、タイマカウンタが65535に達して、次に桁あふれした際に、割り込みを起こすことができます。
その割り込みを起こす度に、4.19424秒を、それまでの経過時間として、どこかに足し込んでいけばいいわけです。


具体的にはこんな感じです。
以下、ATMega328Pの16ビットタイマである、タイマ1を使う前提での説明です。
//CPUのクロック周波数
#define F_CPU 16000000
int32_t msec;//ミリ秒で保存します。

ISR(TIMER1_OVF_vect)  //タイマ1割り込みの定義
{
  msec += (65536L * 1024L * 1000L) / F_CPU ;
}
これは、ミリ秒にするために1000を掛けていますが、これでは大きくなりすぎて、32ビット数値を桁あふれしてしまいます。 そこで、予めCPU周波数を1000で割った数字を用意し、これで割りましょう。
//CPUのクロック周波数を1000で割ったもの
#define F_CPU_DIV1000 16000

int32_t msec;//ミリ秒で保存します。

ISR(TIMER1_OVF_vect)  //タイマ1割り込みの定義
{
  msec += (65536L * 1024L) / F_CPU_DIV1000 ;
}
そして、あとはタイマ関係のレジスタに設定してやれば、その通り動きます。
クラスにしてみました。ATMega328P、Atmel Studio 6.0で確認済み。
Timer.h
#include <stdint.h>

class Timer {
public:
 //タイマを設定し、起動する。
 void StartTimer();

 //タイマを起動してからの経過時間をミリ秒で返す。
 int32_t GetTime();

 //タイマを終了する。
 void EndTimer();
 
 //時間を0にリセットする。
 void ResetTime();
};
Timer.cpp
#include "Timer.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/common.h>

#define F_CPU 16000000L
#define F_CPU_DIV1000 16000L

volatile int32_t current_msec;


void Timer::StartTimer()
{
 current_msec = 0;

 //割り込み禁止
 cli();

 //タイマ/カウンタ1制御レジスタAの設定
 //(タイマ用ピンとして使わない)
 TCCR1A = 0x00; //タイマ関係のピンは標準ポート動作とする
 
 //タイマ/カウンタ1制御レジスタBの設定
 TCCR1B = (1<<CS12)|(1<<CS10);//1024分周でタイマON
 
 //タイマ/カウンタ1割り込みマスク レジスタ設定
 TIMSK1 = (1<<TOIE1);//タイマ1オーバーフロー割り込み許可
 
 //割り込み許可
 sei();
}

int32_t Timer::GetTime()
{
 //16ビットレジスタの読み書きの際には、テンポラリレジスタを使用する。
 //このため、割り込み禁止操作が必要。

 //ステータスレジスタを一時保存する変数
 uint8_t sreg;

 //ステータスレジスタを保存
 sreg = SREG;

 //割り込み禁止
 cli();

 //現在のタイマ値を取得
 uint16_t t = TCNT1;

 //SREGを戻す。これによって割り込み禁止状態が戻る。(SREGのIビットを戻すから)
 SREG = sreg;
 
 int32_t tw = (int32_t)t;
 
 return current_msec + (tw * 1024) / F_CPU_DIV1000;
}

void Timer::ResetTime()
{
 uint8_t sreg;
 sreg = SREG;
 cli();

 //タイマを0にする
 TCNT1 = 0;
 SREG = sreg;

 //経過時間も0にする
 current_msec = 0;
}

void Timer::EndTimer()
{
 TCCR1B = 0;//タイマoff 
}

ISR(TIMER1_OVF_vect)  //タイマ割り込み
{
 current_msec += (65536L * 1024L)/ F_CPU_DIV1000;
}
使い方は、どこかにTimerの実体を定義しておいて、
#include "Timer.h"
Timer timer;

//タイマ起動時に一回だけ実行
timer.StartTimer();

...
...

//時刻を知りたいとき
int32_t time_elapsed = timer.GetTime(); 

...
...

//時間をリセットしたいとき
timer.ResetTime();

...
...

//タイマーが不要になったとき
timer.EndTimer();

こんな感じですかね

あ、そうそう、SREGはavr/common.hに定義されていますので、avr/interrupt.hと合わせてインクルードしておきましょう。
それと、当然ですが、この方法でもミリ秒で符号付き32ビットがいっぱいになるまでしかカウントできませんので、
0x7FFFFFFF / 1000 / 3600 / 24 = 24日程度でいっぱいになります。まあ私の用途では十分です。

2012年4月1日日曜日

AVRのメモリ(SRAM)とプログラムエリア(FLASH)

AVRではメモリ(SRAM)とプログラムエリア(FLASH)が区別される。
SRAMの容量は限られている(ATMega64Aでは4KBしかない)。その上、スタックなどにも使われる。

そこでプログラム中の文字列定数などはFLASHに置きたいが、
普通にCで書くとSRAMに置かれてしまうらしい。

1.PSTR
プログラム中ではPSTRマクロを使って文字列定数を書くことでFLASHにおいてくれる

char* flash_addr = PSTR("constant string on FLASH.");

こんな感じ


2.PROGMEM

avr/pgmspace.hをインクルードし、PROGMEMを頭につけることでFLASHに置いてくれる

PROGMEM char str[] = "some string";


3.PRG_RDB

上記で読み出すときはpgm_read_byteを使用

char c = pgm_read_byte(&str[i]);

2012年1月12日木曜日

ATMega64aのワナ

最近、ATMega64AというATMEL社のマイコンを使っています。
そこで早々にハマってしまった点をご紹介します

といってもデータシートにはちゃんと書いてあるわけで、読まずに悩んでたのがバカだったりするのですが

ハマったのは、ATMEL社のISPである、AVRISP mk2を使ったときのことです。

以前使っていた、Arduinoでも使われているATMega328pなんかだと、MISOもMOSIも素直につなげばよかったので、特に問題はありませんでした。

そのときの感覚のままでISPのMISO、MOSIをATMega64AのMISO、MOSI(PB2、PB3)につないだところ、まったく通信ができません。
おっかしーなーと散々悩んだ挙句、ついに発見しましたデータシート
310ページあたりの、「27.8 SPI Serial Programming Pin Mapping」という章です。

詳しくはデータシートを読んでください。
簡単に言うと、「SPIのIOモジュールはプログラミングインターフェースには使わないよ、SPIプログラミングモードのときはMOSIはPE0、MISOはPE1につなげよ!」ってことだったのです!
ちなみにSCKはPB1でよいです。

なんとまあ・・これで半日潰れてしまいました・・・


2011年11月6日日曜日

Google Cloud SQL

Google Cloud SQLとは?

Google Cloud SQLとは、GoogleAppEngineのアプリケーションから利用できる、リレーショナルデータベースサービスです。
それは、データベースの保守管理や運用について、(Google側で)完全に管理されたサービスであり、
利用者は、煩わしいデータベースの保守管理は不要で、自身のアプリケーションにのみ注力することができます。

データベースの仕様はMySQLに準拠しています。
これにより、データ、アプリケーション、サービスを、簡単にクラウドに載せることが可能になります。
つまり、既存のデータベースをすばやくAppEngineから利用できるようになりますので、
データの可搬性やサービスのマーケットへの投入速度を高めることができます。


アプリケーションやサービスを常に動作させるために、
GoogleCloudSQLはデータを地理的に異なる複数の場所に保存し、信頼性を高めています。

このサービスは現在プレビュー版です。
まもなく、価格についての発表があるでしょう。

機能のハイライト:

・簡単に使えます
データベースの生成、管理、監視のためのリッチなGUIがあります。

・完全に管理されています
データベースは完全に管理されており、データベースのレプリケーションや、パッチの管理など、データベースの管理運用に関わる作業は不要です。

・高い信頼性
今日のサービスやアプリケーションが必要とする信頼性を実現するため、
複数のデータセンターにまたがるデータのレプリケーション機能が組み込まれており、
ひとつのデータセンターがダウンしたとしてもサービスは使い続けることができます。

・GoogleAppEngineやその他Googleサービスとの統合
GoogleAppEngineやその他Googleサービスとの統合により、
複数の製品を簡単に連携させられるようになります。
データをクラウドに配置すれば、より高いパフォーマンスを得られるでしょう。

2011年8月13日土曜日

Google Prediction API --Hello Prediction!--

元ネタ:http://code.google.com/apis/predict/docs/hello_world.html

このページは、PredictionAPIを15分程度で、とりあえず使ってみるサンプルを紹介します。
とりあえずこのサンプルを試したあとに、他のドキュメントを読むとよいでしょう。

Prerequisites 前提条件






The Problem 解決課題


あなたの会社では、電子メールで複数の言語での問い合わせを受け付けていると考えてください。
そしてあなたは、該当する言語の担当者に、電子メールを振り分けなければなりません。
つまりここでの問題は、与えられたテキストが英語なのかスペイン語なのかフランス語なのか判別する、ということになります。

これをするためにあなたは、予測エンジンに学習させるための学習データを作成する必要があります。
一つの学習データは、いくつかのテキストで構成されており、そのテキストの言語を表す、「英語」「スペイン語」「フランス語」のいずれかのラベルが振られているものとします。

学習の後に、任意の言葉や文章を与えると、予測エンジンはそれを上記の言語のうち一番近いものに分類します。


The Solution 解法

Hello Predictionを行う処理の流れは以下のようになります。

1.認証トークンの取得
    PredictionAPIへのリクエストは、すべて認証されている必要があります。 APIはOAuth認証をサポートします。このサンプルでは、OAuthに対応したoacurlコマンドラインツールを使います。最初にトークンをリクエストし、その後のリクエストには、すべてトークンを含める必要があります。

2.学習データのアップロード
    Google Storageに、英語、スペイン語、フランス語を含んだ学習データをアップロードします。 Google Storageにアップロードしたデータのbucket名やオブジェクト名は、学習モデルの一意識別子として使われます。 Prediction APIのリクエストは、この一意識別子により、学習モデルを指定する必要があります。

3.学習
    Prediction APIに、学習データを読み込んで学習するように指示します。 この処理は非同期に行われるため、定期的にサーバーに問い合わせを行って、学習の状態を調べる必要があります。 学習に基づく予測問い合わせを行う前に、学習は完了していなければなりません。

4.問い合わせの実行
    学習の完了後、単語や文章を含んだクエリをサーバーに送信し、サーバーから、そのテキストに対応した言語を受け取ります。 このステップは何回でも実行できます。

このサンプルでは、oacurlコマンドラインツールと、リクエスト送信用のヘルパースクリプトを使用します。
oacurlのヘルパースクリプトは、ライブラリのページにあります。(スクリプトの使い方や、注意点を解説しています。)

oacurlはここからダウンロード

1.認証トークンの取得
oacurlを使用した認証を行う際、インターネットにアクセスでき、ブラウザが使用可能である必要があります。
ダウンロードしたoacurlのjarファイルを置いたディレクトリに移動し、以下のコマンドを実行してください。
このコマンドはブラウザを立ち上げ、Googleアカウントのログインページを表示します。
ログインの後、oacurlがあなたのGoogleアカウントでPrediction APIにアクセスすることを許可するかどうかを聞いてきます。
Prediction APIをアクティブにしたGoogleアカウントでログインすることを忘れないでください。
$ java -cp oacurl-1.2.0.jar com.google.oacurl.Login --scope https://www.googleapis.com/auth/prediction

※このコマンドにより取得したトークンには長めのライフタイムがあり、セッションの最初に一度実行すればOKです。
もし、セッションの途中で認証エラーが発生した場合は、もう一度このコマンドを実行し、再度トークンを取得してください。

2.学習データのアップロード

この学習ファイルをダウンロードしてください。
これは、英語とスペイン語とフランス語の学習データを含んでいます。
学習ファイルのフォーマットは、カンマ区切りのテキストファイルで、2つのカラムと、多数のレコードからなります。
2つ目のカラムは、一つの言語に対するサンプルテキストです。
1つ目のカラムは、サンプルテキストの言語を表すラベル名です。
学習ファイルを開いて、中身を見てみてください。

学習ファイルをGoogle Storage Bucketにコピーしてください。
このサンプルでは、「examplebucket」というbucketを使っていますが、あなた自身のbucketに読み替えてください。
(bucket名は他ユーザーとの間でもユニークでなければならない。)
オブジェクト名については、好きな名前にすることができます。オリジナルの学習ファイルと同じにする必要はありません。

$ gsutil cp ./language_id.txt gs://examplebucket/prediction_models/languages
$ gsutil ls gs://examplebucket
gs://examplebucket/prediction_models/languages

3.学習
次のステップはシステムに学習させることです。
そのためには、先ほどアップロードした学習ファイルのbucket/objectを指定したPOSTリクエストをサーバーに送信します。
リクエストの送信後、学習が完了するまでポーリングします。

このサンプルでは、oauth-train.shと、oauth-check-training.shという、ヘルパースクリプトを使います。
これらのスクリプトファイルをローカルにコピーして、以下のように実行してください。

この学習は、1分以内に終了するはずです。もしそれ以上かかるようなら、障害が発生している可能性が高いです。
学習データをGoogle Storageにアップロードしたか、また、スクリプト実行の際にGoogle Storageのbucket/objectを正しく指定したかを確認してください。
なお、スクリプトを実行する際、gs:// は不要です。

$ ./oauth-train.sh examplebucket/prediction_models/languages
{
 "kind": "prediction#training",
 "id": "examplebucket/prediction_models/languages",
 "selfLink": "https://www.googleapis.com/prediction/v1.2/training/examplebucket/prediction_models/languages"
}

$ ./oauth-check-training.sh examplebucket/prediction_models/languages
{
 "kind": "prediction#training",
 "id": "examplebucket/prediction_models/languages",
 "selfLink": "https://www.googleapis.com/prediction/v1.2/training/examplebucket/prediction_models/languages",
 "modelInfo": {
  "modelType": "classification",
  "classificationAccuracy": 0.95
 },
 "trainingStatus": "DONE"
}

4.問い合わせの実行
学習が完了すれば、サーバーに問い合わせを送信し、予測させることができるようになります。
oauth-predict.shスクリプトファイルをダウンロードし、以下のコマンドを実行して、"muy bueno"が、フランス語、スペイン語、英語のうち、どれに一番近いと判断されるか試してください。

$ ./oauth-predict.sh examplebucket/prediction_models/languages "\"muy bueno\""
{
 "kind": "prediction#output",
 "id": "examplebucket/prediction_models/languages",
 "selfLink": "https://www.googleapis.com/prediction/v1.2/training/examplebucket/prediction_models/languages/predict",
 "outputLabel": "Spanish",
 "outputMulti": [
  {
   "label": "French",
   "score": 0.334130
  },
  {
   "label": "Spanish",
   "score": 0.418339
  },
  {
   "label": "English",
   "score": 0.247531
  }
 ]
}
スコアが最大のものが、一番近いと判断されたもので、それは"outputLabel"で示されているスペイン語となります。

2011年8月12日金曜日

Google Prediction API --Getting Started--

元ネタ:http://code.google.com/apis/predict/docs/getting-started.html

このページでは、Google Prediction API について、それが何なのか、どのように使うのか、さらに詳しいドキュメントのありかについて説明します。


Introduction 導入

このドキュメントは、わずか数分でAPIを試せる、Hello World アプリケーションを含んでいます。
また、APIを使用した、完全なwebサイトの例も2件示します。
1つはスパム検出を行うwebサイトであり、もう1つは、ユーザーの動画の閲覧履歴に基づいて、お勧め動画を提案するwebサイトです。


What Can the Prediction API Do? Prediction APIでなにができるの?

Prediction APIは、パターンマッチングと、機械学習の機能を実現します。
与えられた学習データのセットから、以下のような機能を実現するアプリケーションを作ることができます。

  • ユーザーの過去の閲覧履歴から、そのユーザーの嗜好に合った動画や製品を予測します。
  • メールを、スパムかどうか判断します。
  • 製品レビューが、マイナス評価であるか、プラス評価であるかを分析します。
  • ユーザーの今までの製品の利用履歴から、特定の日にどのぐらいの時間製品を利用するかを予測します。


Prerequisites 必要なもの






Questions, Feedback, and Notifications 質問、フィードバック、通知


Prediction API コミュニティに参加する方法は以下の通りです。




Recommended Reading Order ドキュメントはこの順に読むとよいです

  1. Hello World アプリケーションで、APIを試してください
  2. デベロッパガイドや、リファレンスを読んで、APIの使い方を学んでください。
  3. 料金と利用規約のページで、無料でできることと、料金を確認してください。
  4. 現実世界におけるソリューションの一通りのコーディング例として、example アプリケーションを見てください。
  5. APIを様々な言語から使用するための、helper ライブラリをみてください。


2011年8月8日月曜日

Google Prediction API --Libraries and Sample Code--

元ネタ:http://code.google.com/apis/predict/docs/libraries.html#oacurltraining

このページでは、いくつかの言語からPrediction APIを使うためのヘルパーライブラリを紹介します。
また、よくあるシナリオでAPIを使用するアプリケーションのサンプルを提示します。


Generic Google API Client Libraries



ここでは、Google Prediction APIにアクセスするための一般的なREST形式のAPIを紹介します。
以下の表で、1列目に現在の開発段階を示しています。アルファ版のものもあることに注意してください。
各言語のサンプルも提示していますが、中にはまだサンプルがないものもあります。
必要に応じて他の言語のサンプルを参考にしてください。

Client libraryPublic repositoryAll client library samples
Google APIs Client Library for .NET (alpha)google-api-dotnet-client/.NET samples
Google API Libraries for Google Web Toolkit (alpha)gwt-google-apis/GWT samples
Google APIs Client Library for Java (beta)google-api-java-client/Java samples
Google APIs Client Library for PHP (alpha)google-api-php-client/PHP samples
Google APIs Client Library for Python (beta)google-api-python-client/Python samples
Google APIs Client Library for Ruby (alpha)google-api-ruby-client/Ruby samples



Specialized Google Prediction API Client Libraries


ここでは、Google Prediction API用に作られたAPIについて紹介します。

LanguageLibrary NameLink to the Repository
.NET.NET Prediction API libraryhttp://gpapi.codeplex.com/
BASH scriptoacurlSee the scripts below
JavaPrediction API Java libraryhttp://code.google.com/p/google-api-java-client/wiki/APILibraries#Prediction_API
JavaScript (Experimental)Google Prediction API Javascript LibraryLibrary source is available at https://ajax.googleapis.com/ajax/libs/googleapis/prediction-0.0.1/prediction.js. See information below.
PHPPHP Prediction API libraryhttp://code.google.com/p/predictionapiphpwrapper/source/browse/trunk/GooglePredictionWrapper.php
RGoogle Prediction Client Library for Rhttp://code.google.com/p/google-prediction-api-r-client/
RubyOpen-source Prediction API clienthttp://code.google.com/p/ruby-google-prediction-api/
RubyRubyForge Prediction API clienthttp://rubyforge.org/projects/google-predict/



JavaScript Library (Experimental) --省略--





BASH Using oacurl



注意:oacurlは、現在、OAuth1.0のみサポートしています。

oacurlは、OAuth認証に対応したHTTPリクエストをサポートする、オープンソースのコマンドラインツールです。

製品として販売するようなコードでoacurlを使用することは勧められませんが、
テストやデバックを手っ取り早く実行するときは便利です。

このセクションでは、Predicton APIのREST呼び出しにoacurlを使用したスクリプトを紹介します。

ここから最新バージョンのoacurlを入手してください。

認証トークンの取得
Prediction APIの最初のステップは、OAuth認証トークンの取得です。
以下のスクリプトは認証トークンを要求するリクエストを生成します。
このスクリプトはブラウザを立ち上げ、Googleの認証ページを開きます。
ブラウザに表示されたページで、GoogleアカウントのIDとパスワードを入力します。
するとブラウザは、oacurlにあなたのPrediction APIアカウントにアクセスするための認証トークンを返します。
oacurlがあなたのIDとパスワードを見たり受け取ったりすることはありません。

上記の認証プロセスを実行する際に、oacurlにブラウザを起動させるかそれとも自分でブラウザを立ち上げるか選択することができます。
もし自分で立ち上げることを選んだ場合、Googleアカウントのログインページを開くためのURLを受け取ります。
自分で立ち上げる場合は、 --nobrowser フラグをつけてコマンドを実行してください。

以下のコマンドは、oacurlを使ってOAuth認証を行うコマンドです。
oacurlのJARファイルは、ダウンロードしたローカルファイルを指すように変更してください。
$ java -cp oacurl-1.2.0.jar com.google.oacurl.Login --scope https://www.googleapis.com/auth/prediction
認証トークンの有効期限は長いので、認証は一度行えばOKです。
認証後は、oacurlはトークンを見つけると自動的にそれをリクエストに含めますので、
認証について特に気にする必要はありません。


学習
oauth-train.sh
#!/bin/bash
# Train a prediction model.
# Usage: oauth-train.sh MODEL_NAME

ID=$1
KEY=`cat googlekey`

post_data="{\"id\":\"$ID\"}"

# Train the model.
java -cp ./oacurl-1.2.0.jar com.google.oacurl.Fetch -X POST \
-t JSON \
"https://www.googleapis.com/prediction/v1.3/training?key=$KEY" <<< $post_data
echo
このスクリプトは、Google Storageにアップロードした学習データを使っての学習を行います。

注意:このスクリプトを実行する際には、Google Storageのアクセスキーを"googlekey"という名前のファイルに保存して、スクリプトからアクセス可能な場所に置いておく必要があります。 「アクセスキー」は、Google APIs Consoleから取得できます。
このスクリプトは、以下のように使用します。
$ oauth-train.sh mybucket/myobject


学習状態の取得
oauth-check-training.sh
#!/bin/bash
# Check training status of a prediction model.
# Usage: oauth-training.sh MODEL_NAME

DATA=$1
KEY=`cat googlekey`

# Encode the model name.
MODEL=`echo $DATA | perl -pe 's:/:%2F:g'`

# Check training status.
java -cp ./oacurl-1.2.0.jar com.google.oacurl.Fetch -X GET \
  "https://www.googleapis.com/prediction/v1.3/training/$MODEL?key=$KEY"
echo

このスクリプトは、モデルの学習状態をチェックします。
このスクリプトも、Google Storageのアクセスキーを"googlekey"という名前のファイルに保存して、アクセス可能な場所に置いておく必要があります。

問い合わせの実行
oauth-predict.sh
#!/bin/bash

# Run a prediction against a model.
# Usage: oauth-predict.sh MODEL_NAME DATA

DATA=$1
INPUT="$2"
KEY=`cat googlekey`
MODEL=`echo $DATA | perl -pe 's:/:%2F:g'`
data="{\"input\" : { \"csvInstance\" : [ $INPUT ]}}"

java -cp ./oacurl-1.2.0.jar com.google.oacurl.Fetch -X POST \
-t JSON \
"https://www.googleapis.com/prediction/v1.3/training/$MODEL/predict?key=$KEY" <<< $data
echo
このスクリプトは判断のリクエストを送信します。 このスクリプトは、複数のテキストや数値の列を処理します。 このスクリプトも、Google Storageのアクセスキーを"googlekey"という名前のファイルに保存して、アクセス可能な場所に置いておく必要があります。
$ oauth-predict.sh mybucket/myobject "col1, col2 ..."
データリストは、全体をダブルクォーテーション(")で囲む必要があります。 そして、カラムごとにカンマで区切ります。 カラムが文字列データの場合、さらにシングルクォーテンション(')で囲む必要があります。 カラムが数値データの場合は、クォーテーションは不要です。 以下にいくつか例を示します。
oauth-predict.sh example/bucket "'some string data', 'singleval', 123 "
oauth-predict.sh example/bucket "1234, 'Man\'s best friend' "
oauth-predict.sh example/bucket "1234, 3345" # Numerical data does not need additional quotes.