2015年11月12日木曜日

Installing MATLAB Psychtoolbox on Windows 10

PC spec
Dell Inspiron 13 7000 (2-in-1)
Windows 10 Home 64bit
Core i3-6100U

It was the first time to use a Windows 10 PC for me. So I can't tell what causes this slow processing.... Anyway, I successfully installed Psychtoolbox onto Windows 10 PC with MATLAB 2014b after some struggles.

First I downloaded and installed MATLAB 2015a and Psychtoolbox, but MATLAB crashed when I called Screen function. Then I installed 2014b instead of 2015a, and MATLAB told me to install Gstreamer, which is a familiar comment for me. After installing Gstreamer, the screen function worked. I don't know the reason of the crash first I met.

** P.S.
Psychtoolbox 3 with MATLAB 2015a woked on Windows 10 PC.

2015年11月9日月曜日

MATLAB Connection using UDP (TCP/IP)

時間ないので,暫定版メモ。
今度修正します。
Pscyhtoolboxのpnetという関数を使用します。

UDP Port 5000に接続,タイムアウトを0.5秒,パケット送信がなくなると終了。

@MATLAB

sock = pnet('udpsocket',5000);
pnet(sock,'setreadtimeout',0.5)
dataP = 1;

try
    while dataP~=0
        dataI = pnet(sock,'read');
        disp(dataI);
        dataP = pnet(sock,'readpacket');
    end
catch
    disp('Closed_ERROR')
end

pnet(sock,'close')


おわり。

これで,UDPポートを使ってデータを取得するソフトから,MATLABにリアルタイムにデータを取り込むことができます。

2015年10月5日月曜日

Wait signals and proceed

双方向で通信してる時にはこういうのって必要になることありますよね。
シリアル通信における待ちプログラムについて,MATLABとArduinoの両方で書いてみます。
Sometimes you needs to wait until certain signals come in serial communication. Here I'll describe it in Arduino and MATLAB codes.

一番簡単なのは,こうです。
The simplest one would be

@Arduino

Serial.begin(115200);
while (Serial.available() == 0) {
      delay(1);
}

// CODE //

@MATLAB

s = serial('COM1');
set(s,'BaudRate',115200);
fopen(s);
while (s.BytesAvailable==0)
      WaitSecs(0.001);
end

%% CODE %%

fclose(s);

2つのコードはほぼ同じであることが分かると思います。あとは,特定の文字が入力された時のみ次のステップに進むとかもありますね,書き方はたくさんありますが,例えばこうしてみます。
You can see the two codes are essentially the same. In another case, you have to proceed a program only after a particular character is input. You can write like this for example.

@Arduino

byte WaitingFlag = 1;
while (WaitingFlag == 1) {
    while (Serial.available() == 0) {
      delay(1);
    }
    int str = Serial.read();
    if (str == 'R') {
      WaitingFlag = 0;
    }
}

@MATLAB

WaitingFlag = 1;
while (WaitingFlag)
   while (s.BytesAvailable==0)
        WaitSecs(0.001);
   end
   if strmatch(fgets(s),'R')
        WaitingFlag = 0;
   end
end

どちらも,WaitingFlagが1の間はwhile文を繰り返します。ただし,その中にもう一つwhile文がありますので,何か信号が入ってくるまではここから出れません。出たと思ったら,if文によってそれが目的の文字かどうかが照合され,マッチしていたらWaitingFlagを変更して,while文を抜ける,というロジックになってます。
In both programs, the while sentence is repeated as long as Waitingflag = 1. However, before that, an additional while sentence loops until some signals come to the port. After signals come and processing exits from the while loop, the if sentence judges whether the character is expected one or not. If it is not, you cannot exit from the loop. lol







2015年9月20日日曜日

Arduino: Pointer

ポインタというものがC言語(Arduino)では出てくる。これに関して分かりやすく説明しているページが見つけられなくてとってもこまった。
I couldn't find good explanations for a pointer function in C language on the Web and wasted my time.

今回行いたいのは,作成した関数から複数の戻り値(数値の配列)を得ること。MATLABだと超簡単なんだけど,C言語では基本的にはできないらしい。そこで使用するものが,ポインタというもの,らしい。
This time, I want to get an array of values as the return value of a function. In MATLAB it is very easy to write but C does not allow such a program. Instead, "pointer" enables us to achieve  almost the same thing.

結局,以下のように書いたら上手くいきました。MATLABでいうと,
In MATLAB, to get an array of values as the return value, you write

function main
pointer = testFunc;
disp(pointer)

function pointer = testFunc
for i = 1:6
   pointer(i)=i;
end

これで得られる配列を得るためには,Cだとこんな感じになる。
but in C, you write something like that.

void setup() {
  Serial.begin(115200);
}

void loop() {
  int pointer[] = {0, 0, 0, 0, 0, 0}; //(1)
  // the size of pointer is 6

  // Fucntion
  testFunc(pointer); //(2)

  // print on a serial monitor
  for (byte i = 0; i < 5; i++) {
    Serial.print(pointer[i]);
    Serial.print(',');
  }
  Serial.write(10); // new line character
  delay(1000);
}

void testFunc(int *a) { //(3)
  // put pointer as an argument
  for(byte i = 0; i<5; i++) {//(4)
    *a = i;
    ++a;  
    // the pointer proceeds from 0 to 5.
    // this maybe the same that a[0]=i ... a[5]=i.
  }
  
  // no "return", but the pointer is updated.
}


あまり説明が見つからなかったこともあり,ポインタについての理解は足りませんが,実用的な使い方としての解説をしてみます。


(1) int pointer[] = {0, 0, 0, 0, 0, 0};

で,ポインターと呼ばれるものをつくります。これは,ポインターとか言わずに,とりあえず欲しい配列入れるための変数を宣言すると考えましょう。今回はテストとして0を入れてますが,pointer[6];として,サイズだけ決めてもいいのかもしれません。
this made a pointer, and it is better to regard as just a variable which will contain an array of values. This time I write {0,0,0,0,0,0} but it maybe OK to state int pointer[6].


(2) testFunc(pointer); 

戻り値は書いてませんが,ポインターが勝手に更新されてくれるのでOKです。
this doesn't include the return value, but it's OK because the pointer gets the return value.

(3) void testFunc(int *a) {

引数を「*a」としているのがポインターとして使うというしるしです。きっと。
The asterisk maybe the sign to use an argument as a pointer. 

(4)for(byte i = 0; i<5; i++) {
     *a = i;
      ++a; 
   }

for文の中で,何やらポインターの数を増やしつつ,ポインターに値を代入しています。これがどういう仕組みかはわかりませんが,MATLABでいうと,for i=1:6; a(i)=x; end と一緒ということでしょう。もちろん,厳密な意味は違うのでしょうが,表層的にはこれでいいかと。
In the for loop, the value of the pointer increases and at the same time i is substituted for the pointer valuable. This may mean that for i=1:6; a(i)=x; end in the MATLAB language at least superficially.

とりあえず,これさえ理解できれば,戻り値に配列を設定するのは実装できるかな,と思います。根本的な間違いがあれば教えて下さい。

Arduino: function definition

初歩的ですが,関数を定義する時のルール。MATLABに慣れてるとわかんないだよ。
Cause I get used to MATLAB, even function definition is confusing to me...

void loop() {
   int a = myFunc(); // must be defined.
}

// must be defined as the type of the return value.
// if the function does not return any values, void is used.

int myFunc() {
  int x = 1+2;
  return x;
}

引数を使うときは,またあとで。


Arduino: Character to Integer

Serial通信はアスキー文字列としてデータを送受信します。つまり,20という数値を送ったとしても,それは数字で合って,数値ではありません。その後の処理を続けるには数値に変換したいわけです。
Serial communication send and receive data as ASCII characters not values.

そんなときは,atoiという関数を使います。
Use atoi (alphabet to integer) function.

void loop(){
   char * val =;   // * is important
   int a;

   // when 3-digits values are input
   for (int i =0;i<=3; i++){
     val[i] = Serial.read();   // [x] is important.
   }
   a = atoi(val); //wrong: a = atoi(val[x]);
}

255,255,255,255などのデータを送受信するときは,charではなくてとりあえずintで読んでから,カンマや改行文字などがくることをif文で判別,そうじゃないとき(数字のとき)には数字を“貯めて”から数値に変換,としたらとりあえず回りました。もっと簡単でいい方法もあるとは思いますが。
If you want to read data such as 255,255,255,255, you (1) read the data as int, (2) discriminate commas and newline characters using if statements, (3) "store"  the numeral characters, and (4) convert them into int values. It works but I guess better and simpler ways exist.

Arduino: MsTimer2, FlexiTimer2

Arduinoのタイマー機能についてです。
心理実験に使用することを目的としているので,一定の周波数でサンプリングしたいわけです。
I want analog data at a constant sampling rate to use an Arduino in psychological experiments.

Arduinoの時間関係の関数の簡単な奴としては,

millis()
 起動からの時間をミリ秒で返す,
micros()
 起動からの時間をマイクロ秒で返す
delay()
 次の処理までミリ秒単位で待つ

などの関数があります。

しかし,こいつらを使用して頑張ってみても,処理をしている間の遅れが蓄積していき,FB制御をしてもうまいこと一定間隔サンプリングができませんでした。この辺は私のプログラミング能力が不足しているためですが…。
I could not fulfill my purpose by using these functions.

ということで,時間割り込みとかなんとかいう関数を使用します。設定した間隔で処理を実行していくれる関数です。Arduino公式HPにて公開されているライブラリからダウンロードして下さい。
Then I used something time interruption functions. You need to download library files from the Arduino HP.
http://www.pjrc.com/teensy/td_libs_MsTimer2.html

MsTimer2
 ミリ秒単位の間隔で指定した処理を実行
FlexiTimer2
 マイクロ秒単位の間隔で指定した処理を実行

さて,実行してみましたが,一定間隔サンプリングは上手くいきませんでした。マジむかつきます。
I simply implemented it, but again I failed. Really annoying.

と思ったら,一定間隔で処理したい関数に

interrupts();

を入れることで問題が解消しました。これ見つけるのに半日使いました。
But congratulations, the problem was fixed after I put the above line into the function which I wanted to process at a constant intervals.

FlexiTimer2では,interrupts();を入れたらエラーが出て使えませんでした。FlexiTimer2を使いたいのですが,それ以上考えるのは面倒なので諦めました。誰か解決法教えてください。
ちなみに,dueでは両方の関数が使えず…。時間が立てば対応してくれるでしょうか?



アナログセンサーから一定間隔サンプリングをして,それをシリアルモニタに出力
A sketch which samples data from an analog port at a constant interval and outputs the data to a serial monitor.


#include <MsTimer2.h>

const int A0sensor = A0;

int sensorValue0;

void setup() {

  Serial.begin(115200);
  int a = 10;                    // 10ms intervals
  MsTimer2::set(a,sampling); 
  MsTimer2::start();
}

void loop() {

  // nothing
}

void sampling(){

   interrupts();
   sensorValue0 = analogRead(A0sensor);
   Serial.println(sensorValue0);
}

2015年9月18日金曜日

Arduino: SoftwareSerial

Arduinoのシリアル通信はくっついているUSBじゃないデジタルポートでも行える。
MEGAとかdueだと,メインのそれ以外の専用ポートもいくつかくっついているみたい。
Arduino can communicate to other devices by using digital ports.

Arduino UNOだと,デジタル0と1番以外を割り当てる。
0と1はもともとSoftwareSerialを使わずにシリアル通信をするときに使うものらしい。なので,最初からTXとRXという表示が付いている。今回は簡単なSoftwareSerialを使います。
In Arduino uno, we should use digital ports other than 0 and 1 when using SotwareSerial.


#include<SoftwareSerial.h>
SoftwareSerial Serial1(2,3); 
// You should define before void setup()
// The name of a software serial is arbitrary.
// eg., SoftwareSerial mySerial(2,3)

void setup() {

  Serial1.begin(115200);
}

void loop() {


  Serial1.println("hello");

  delay(500);


}


こんな感じ。

もうひとつSoftwareSerialポートを作成して,一台のArduinoで通信ごっこをして試すことが可能。
You can make another SoftwareSerial port and communicate to each other in the Arduino.

SoftwareSeria2 Serial1(4,5);// before voidsetup()

Serial2.begin(115200);// in void setup()

int SerialState = Serial2.read();// in void loop()

という感じ。

読み込んだものを確認するためには,シリアルモニタで確認したいので,そんな時には
to confirm the data, use the normal Serial and write the input data on a serial monitor.

// normal "Serial" is already defined by default.
// So you need not to define it.
Serial.begin(115200);// in void setup()

Serial.write(Serial2.read()); // in void loop()


こうすれば,シリアルモニタに,読み込んだものを出力できる。

charで読み込んだ場合は,writeではなくてprintを使う。
When you read data as char, you can use Serial.print to input them to the serial monitor.

char SerialState = Serial2.read();
Serial.println(Serial2.read());


ちなみに,
The case the types of variables are different,

Serial.println(Serial2.read());

では,違う表示になるので試してください。








2台のArduinoをつなぐ時にも,上のコードを適当に分けて書けばいい。
When you connect two Arduinos.

1台目TX-2台目RX,1台目RX-2台目TXを繋ぐのは当たり前で間違える人はいないだろうけど,1台目GRD-2台目GRDも繋がないと,電気的におかしなことになるので注意。
Note that you need to connect two GNDs.


また,プログラムを書き込む時には,2台を繋ぎながらだと書きこみエラーが出て,怖いので絶対にはずしましょう。

覚書はじめます。

あまりに物忘れが激しく,少し前に作ったものをことごとく忘れていくので,メモすることにしました。
過去のものも,遡って少しずつためるかもしれません。