ラベル arduino の投稿を表示しています。 すべての投稿を表示
ラベル arduino の投稿を表示しています。 すべての投稿を表示

2008年6月29日日曜日

yahooweather teruteru②

てるてるマイコンコードを色々いじってみる。

てるてるコードその1

てるてるコードその2

voltmeterが動かなくなったのですが

文字列の後にこの数値ひろえー命令をあれは出していて
サイトが時々更新されて
その文字列が無くなってしまう時があるようです。

文字列が復活したのでひとまず動きそうだ!
と思ってもう一度動作確認中なのですが
…またウェブから値がやってこない病が…

2008年6月28日土曜日

yahooweather teruteru

utano

てるてるリベンジ中。

yahoo news(英語)のお天気サイトから
お天気情報をひっぱって、
更に曇りなら1、晴れなら2、雨なら3にするというPHPを書きました。

これのソースコードを見ると、
本のp.131みたく <weather:1>とか出ます。

で、マイコン側のプログラムはほとんどそのままに、
このPHPを読んで<>内の数字を記憶して
その数字をintにして、
if文で1のときは曇りなので曇りLED光らせてねっていう
void teruteru()をつくりました。コンパイルは成功。
yahooweatherてるてるマイコンコード

でも光りませんでした。

たまにvoltmeterでもそうなのですが
ウェブを要求した後その内容を読み込んでくれない時が発生します。

うーむぅ。

しょうさまたすけて。

2008年6月27日金曜日

voltmeter完成

voltmeterが動きました!
このプロジェクトはアメリカの大気の汚染予報を教えてくれる、
AIRNowというサイトからNYの大気汚染度の現在情報を拾って
電流計メーター(アナログ)に出力させるというものです。
よく写真を見ると針が右にすこし振れています。



結局あの後いじったのは:
☆ルーターのIPを設定
(chapter3のp.84参照、ルータのIPアドレス調べ方)
☆ウェブから情報をはぎとるPHPのパーミッション変更
(Octalを707に、きょんちゃんアドバイス)

どれが果たして功を奏したのかw

全体像はこんな感じ:


あ、FT232Rのシリアル変換はさしっぱだっただけで無関係です。
LEDがナウシカのオームの目みたい…


2番目が光ってるのでHTTPrequest()してます。
情報を読み取るウェブ(PHP)を要求しているのです。
Arduinoの画面ではこんな感じ:

マイコンとXPortとウェブの三角関係②

本に沿って回路つくってコードを書くと、
ご丁寧に今どういう通信状態なのかをLEDで判断する事が出来ます。

でも大体サーバに接続しようとしてる所で
ピコピコ止まりだったので、
もう少し通信状態を可視化しようと思いました。

まずAcknowrichとshokai様から頂いたSocketClientで実験

XPort接続中。IPアドレスは192.168.0.150 ポート番号は50001に設定済。



ではSocketClientからXPortさんにアクセスしてみましょう



するとシリアル側(Acknowrich)ではI192.168.0.110と出る。



IはIncomeのIなので、情報が伝わった事はわかるけど
なんでIPアドレスが変わるんじゃ?
本でXPort設定のところでルーターのIPを指定する所あるけど
そこと関係があるんでしょうか??

まぁ一旦おいといて
シリアル側から、欲しいウェブがあるサーバに行ってねってお願いしてみる



…ただのテキスト扱いっぽいんですけど
GETとかHOSTも入れてみたけど同じ。

SocketClientを終了すると



ちゃんとDisconnectのDが現れる。

つながっているようでつながっていないような…
何が問題なんじゃー。

マイコンとXPortとウェブの三角関係①

utano

夜12時にDNPを訪れる!

てるてる坊主を作るにしても
とりあえず本にあるArduinoに書き込む、
ウェブを取り込むコードを理解しなければだめでしょう

ということで回路や本やら5時間くらいにらめっこして
ようやく本が書いてるコードが意図する所がつかめました。

マイコンで取ってきて欲しいウェブがあるサーバを呼ぶ
私の場合SFCなのでコマンドプロンプトでping web.sfc.keio.ac.jpを唱えて
SFCサーバのIPアドレスをゲットする。
そしてXPortに通じる呪文にする C133.27.4.40

接続が行われたらすかさずウェブを呼び出す
GET /~t05541ss/ほにゃほにゃ.php HTTP/1.0\n
HOST: web.sfc.keio.ac.jp

で、そのウェブのテキストをがーって読んで
その中から数字をゲットしてくる
その数字を更に数値にする(テキストのままだから)
あらかじめマイコンが読みやすい様に
そのウェブはPHPですっきりまとめてあります
HTMLタグ全部どけて、この文章の後に来る数字を表示してねって感じで。

で、その数値によってArduinoのoutputである電流計の触れ幅が変わる

っちゅうわけです。構造は分かるけど
XPort経由でウェブを問い合わせるのがなんかだめ。

ちゃんと動いているのか動作チェックする。

マイコンとXPortとウェブの三角関係②につづく。

p160までのarduino code

tmgです。
たまにはためになることを

今xportで、通信してピンポンをするシーソー作ってます。文字だけ見るとなんのこっちゃって感じですね。
p160までのコードです。エラーはないはず!
resetdeviceのくだりはまるっと無視しました。だってXportからそんなピンでてないんだもん…


----------------------

/*
pong cliant
Langage: Writing/Arduino

このプログラムはArduinoで、ネットワークにつながった
ピンポンのパドルをコントロールすることを可能にする

*/

//Lantronix deviceのステータスを定義する
#define disconnected 0
#define connected 1
#define connecting 2

//I/Oピンを定義する
#define connectButtonPin 2
#define rightLED 3
#define leftLED 4
#define connectionLED 5
#define connectButtonLED 6

int inByte= -1;
int status = disconnected;

byte connectButton = 0;
byte lastConnectButton = 0;

byte paddleMessage = 0;
byte connectMessage = 0;

void setup(){
pinMode(connectButtonPin,INPUT);
pinMode(rightLED,OUTPUT);
pinMode(leftLED,OUTPUT);
pinMode(connectionLED,OUTPUT);
pinMode(connectButtonLED,OUTPUT);

Serial.begin(9600);

}

void loop(){
readSensors();
setLeds();
stateCheck();
}

void readSensors(){
int leftThereshold = 500;//適宜
int rightThreshold = 420;//変えてね

int x = analogRead(0);
delay(10);

if (x > leftThereshold){
paddleMessage = 'l';
} else if (x > rightThreshold){
paddleMessage = 'r';
} else {
paddleMessage = 0;
}

connectButton = digitalRead(connectButtonPin);
connectMessage = 0;
if (connectButton == HIGH){
if (connectButton != lastConnectButton){
digitalWrite(connectButtonLED,HIGH);
connectMessage = 'x';
}
}
lastConnectButton = connectButton;
}

void setLeds(){
switch (paddleMessage){
case 'l':
digitalWrite(leftLED,HIGH);
digitalWrite(rightLED,LOW);
break;
case 'r':
digitalWrite(rightLED,HIGH);
digitalWrite(leftLED,LOW);
break;
case 0:
digitalWrite(leftLED,LOW);
digitalWrite(rightLED,LOW);
}

if (connectMessage !=0){
digitalWrite(connectButtonLED,HIGH);
}
else{
digitalWrite(connectButtonLED,LOW);
}

if (status == connected){
digitalWrite(connectionLED,HIGH);
}
else {
digitalWrite(connectionLED,LOW);
}
}

void stateCheck() {
switch (status){
case connected:
while (Serial.available() > 0){
if(Serial.read() == 'D'){
status = disconnected;
}
}
if (paddleMessage != 0) {
Serial.print(paddleMessage);
paddleMessage = 0;
}

if (connectMessage != 0){
Serial.print(connectMessage);
connectMessage = 0;
}
break;

case disconnected:
if (connectMessage !=0){
deviceConnect();
connectMessage = 0;
}
break;

case connecting:
if (Serial.available()){
inByte = Serial.read();
if (inByte == 'C'){
status = connected;
}
else{
deviceConnect();
}
}
break;
}
}

void deviceConnect() {
Serial.print("C192.168.0.182/50001\n\r");//←ここ自分のに変えてくださいね
status = connecting;
}

void blink(int howManyTimes){
for (int i=0; i< howManyTimes; i++) {
digitalWrite(connectButtonLED,HIGH);
delay(200);
digitalWrite(connectButtonLED,LOW);
delay(200);
}
}

2008年6月25日水曜日

てるてる坊主(途中)

o9no大先生の力によって
livedoorお天気のRSSから天気を表示するPHPが出来ました。
そこから更にマイコンが晴れとか雨とか読めるように
雨なら1、などの数字を割り当てるPHPを書きました。

問題はマイコンなのです。
XPortを通じて、
ライブドアお天気の天気を数字に」ファイルを呼び出して
ウェブの情報をだーって読んでっていう本に載ってるプログラムを
てるてる仕様に変えなきゃいけないんですが…

そもそもの電流計のやつも動いてくれないので
(でもなんかわかりそうな気もする)

雲行きがあやしくなってきました。

2008年6月23日月曜日

voltmeter

utano

chapter4のvoltmeterのソースコードです。
一応コンパイルが通りました。
でも、void blink()のところがなんかきれいにブログで出なかったので
そこは本をみて調整してください。
つかHTMLタグとかがブログにアップするときにひっかかるので…

//Defines for the program's status (used for status variable):
#define disconnected 0
#define connecting 1
#define connected 2
#define requesting 3
#define reading 4
#define requestComplete 5

//Defines for I/O pins:

#define connectedLED 2 //indicates when there's a TCP connection
#define requestingLED 3 //indicates a HTTP request has been made
#define readingLED 4 //indicates a device is reading HTTP results
#define requestCompleteLED 5 //indicates a successful read
#define programResetLED 6 //indicates reset of Arduino
#define deviceResetPin 7 //resets Lantronix Device
#define meterPin 11 //controls VU meter; has to be one of thePWM pins 9-11

//Defines for voltmeter
#define meterMax 130 //max value on the meter
#define meterScale 150 //my meter reads 0-150

//variables
int inByte = -1; //incoming byte from serial RX
char inString[32]; //string for incoming serial data
int stringPos = 0; //string index counter

int status = 0; //Lantronix device's connection status
long lastCompletionTime = 0;//counter for delay after last completion

void setup(){
//set all status LED pins and Lantronix device reset pin:
pinMode(connectedLED, OUTPUT);
pinMode(requestingLED, OUTPUT);
pinMode(requestCompleteLED, OUTPUT);
pinMode(programResetLED, OUTPUT);
pinMode(deviceResetPin, OUTPUT);
pinMode(meterPin, OUTPUT);
//start serial port, 9600 8-N-1
Serial.begin(9600);
//reset Lantronix device
resetDevice();
//blink reset LED
blink(3);
}

//Take the Lantronix device's reset pin low to reset it
void resetDevice(){
digitalWrite(deviceResetPin, LOW);
delay(50);
digitalWrite(deviceResetPin, HIGH);
//pause to let Lantronix device boot up
delay(2000);
}

//Blink the reset LED
void blink(int howManyTimes){
int i;
for(i=0; i digitalWrite(programResetLED, HIGH);
delay(200);
digitalWrite(programResetLED, LOW);
delay(200);
}
}

void loop(){
stateCheck();
setLEDs();
}

void stateCheck(){
switch(status){
case disconnected:
//attempt to connect to the server
deviceConnect();
break;
case connecting:
//until you get a C, keep trying to connect: read the serial port
if(Serial.available()){
inByte = Serial.read();
if(inByte == 'C'){ //'C' in ASCII
status = connected;
}
else{
//if you got anything other than a C, try again
deviceConnect();
}
}
break;
case connected:
//send HTTP GET request for CGI script
httpRequest();
break;
case requesting:
lookForData();
break;
case reading:
readData();
break;
case requestComplete:
waitForNextRequest();
}
}

void deviceConnect(){
//send out the server address and wait for a "C"byte to come back.
//fill in your serves numerical address below
Serial.print("C192.168.0.150/80\n");
status = connecting;
}

void httpRequest(){
//make sure you've cleared the last byte from the last request
inByte = -1;
//reset the string position counter
stringPos = 0;
//make HTTP GET request and fill in the path to your version of the CGI script
Serial.print("GET /~t05541ss/public_html/voltmeter_130131.php HTTP/1.0\n");
//fill in your server's name
Serial.print("HOST:web.sfc.keio.ac.jp\n\n");
//update the state of the program
status = requesting;
}

void lookForData(){
//wait for bytes from server
if(Serial.available()){
inByte = Serial.read();
//if you get a "<", what follows is the air quality index. you need to read what follows "<"
if(inByte == '<'){
stringPos = 0;
status = reading;
}
}
}

void readData(){
if(Serial.available()){
inByte = Serial.read();
//keep reading until you get a ">"
if(inByte !='>'){
//save only ASCII numeric characters (ASCII 0-9)
if((inByte >= '0') && (inByte <= '9')){
inString[stringPos] = inByte;
stringPos++;
}
}
//if you get a ">" you've reached the end of the AQI reading
else{
interpretResults();
}
}
}

void interpretResults(){
//convert the string to a numeric value
int airQuality = atoi(inString);
//set the meter appropriately
setMeter(airQuality);
lastCompletionTime = millis();
status = requestComplete;
}

void setMeter(int desiredValue){
int airQualityValue = 0;
//if the value won't peg the meter, convert it to the meter scale and send it out
if(desiredValue <= meterScale){
airQualityValue = (desiredValue * meterMax/meterScale);
analogWrite(meterPin, airQualityValue);
}
}

void waitForNextRequest(){
if(millis() - lastCompletionTime >= 120000){
//reset Lantronix device before next request
resetDevice();
status = disconnected;
}
}

void setLEDs(){
/* Except for the disconnected and connecting states,
all the states of the program have corresponding LEDs.
so you can use a for-net loop to set them by turning them all off except for the one that has
the same number as the current program state
*/
for(int thisLED = 2; thisLED <= 5; thisLED++){
if(thisLED == status){
digitalWrite(thisLED, HIGH);
}
else{
digitalWrite(thisLED, LOW);
}
}
}



2008年6月11日水曜日

感圧センサが反応したよ

utano

stk氏とコラボレーションしてp.102まで終わりました。



感圧センサ動いた~♪
ジャンプワイヤが虹みたいでかわいいでしょ。

p.101のArduinoコード:

/* Analog sensor reader
Language: Arduino

Reads an analog input on Analog in 0, prints the result as an ASCII-formatted decimal value.

Connections:
FSR analog sensors on Analog in 0
*/

int sensorValue;//outgoing ADC value

void setup(){
//start serial port at 9600bps
Serial.begin(9600);
}

void loop(){
//read analog input
sensorValue = analogRead(0);
//send analog value out in ASCII decimal format
Serial.println(sensorValue, DEC);
//wait 10ms for next reading
delay(10);
}


p.101-102のProcessingコード:

import processing.serial.*;

int linefeed = 10;//linefeed in ASCII
Serial myPort;//the serial port
int sensorValue = 0;//the value from the sensor

void setup(){
size(400,300);
//list all the available serial ports
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil(linefeed);
}

void draw(){
//twiddle your thumbs
}

void serialEvent(Serial myPort){
//read the serial buffer
String myString = myPort.readStringUntil(linefeed);
//if you got any bytes other than the linefeed
if(myString != null){
//trim off the carriage return and convert the string to an integer
sensorValue = int(trim(myString));
//print it
println(sensorValue);
}
}

2008年6月1日日曜日

p.69 Arduino

utano

スイッチの回路が間違っていたのを修正したら
ちゃんとボタン操作が出来るようになりました。
ようやく完成です♪
教えられる様にまたコードを見ておきます。

さてp.69に、p.59で書いたArduinoプログラムをいじり直す箇所があります。
wrap the whole of the loop() method in an if() statement like this:
という英語を解釈すると、以下の赤い文字を足すという作業になると思います。

int leftSensor = 0;
int rightSensor = 1;
int resetButton = 2;//この数字がpinModeでの値になります
int serveButton = 3;//こっちも上と同じ

int leftValue = 0;
int rightValue = 0;
int reset = 0;
int serve = 0;

void setup(){
Serial.begin(9600);
pinMode(resetButton, INPUT);//int resetButton = 2;としたので、2ピンにボタンをつけます
pinMode(serveButton, INPUT);//同じく
}

void loop(){

//check to see whether there is a byte available to read in the serial buffer
if(Serial.available() > 0){

//read the serial buffer, you don't care about the value of the incoming byte
//just that one was sent
int inByte = Serial.read();

//the rest of the existing main loop()

leftValue = analogRead(leftSensor);//ピン番号は、Buttonの時と同じ。最初のint leftSensor指定の0
rightValue = analogRead(rightSensor);//上と同じ理由で1
reset = digitalRead(resetButton);//上と同じ
serve = digitalRead(serveButton);//上と同じ

Serial.print(leftValue, DEC);
Serial.print(",");
Serial.print(rightValue, DEC);
Serial.print(",");
Serial.print(reset, DEC);
Serial.print(",");
Serial.println(serve, DEC);
}
}

Now you can play Monski pong

utano

p.68のNow you can play Monski pong!までのソースコードです。
小さいボールを四角で跳ね返すピンポンゲームみたいになります。
でもなんか反応わるい時もあるので合ってるか自信ないです。

import processing.serial.*;//import the Processing serial library

int linefeed = 10;//Linefeed in ASCII
Serial myPort;//シリアルポートの名前をmyPortにする宣言

float leftPaddle, rightPaddle;
int resetButton, serveButton;
int leftPaddleX, rightPaddleX;
int paddleHeight = 50;
int paddleWidth = 50;

//センサの最大値と最小値
float leftMinimum = 250;
float rightMinimum = 270;
float leftMaximum = 540;
float rightMaximum = 530;

//ボールを足す
int ballSize = 10;
int xDirection = 1;//horinzontal direction ひだり-1 みぎ1
int yDirection = 1;//vertical direction うえ-1 した1
int xPos, yPos;//ボールのx,y座標

boolean ballInMotion = false; //whether the ball should be moving
int leftScore = 0;
int rightScore = 0;

PFont myFont;
int fontSize = 36;

void setup(){
//ウィンドウサイズ
size(640,480);
//ボールをスクリーンの真ん中にもってくる=幅の2分の1の座標指定
xPos = width/2;
yPos = height/2;

//使えるシリアルポートをリストにして挙げる
println(Serial.list());
//Arduinoをつなげているシリアルポートナンバーがあてられているリストの番号を[]に入れてmyPortとする
myPort = new Serial(this, Serial.list()[1], 9600);
//read bytes into a buffer until you get a linefeed (ASCII,10);
myPort.bufferUntil(linefeed);

//initialize the sensor values
leftPaddle = height/2;
rightPaddle = height/2;
resetButton = 0;
serveButton = 0;

//initialize the horizontal paddle positions
leftPaddleX = 50;
rightPaddleX = width - 50;

noStroke();

//create a font with the third font available to the system
PFont myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);
}

void draw(){
background(0);
//draw the left paddle
rect(leftPaddleX, leftPaddle, paddleWidth, paddleHeight);

//draw the right paddle
rect(rightPaddleX, rightPaddle, paddleWidth, paddleHeight);

//calculate the ball's position and draw it
if(ballInMotion == true){
animateBall();
}

// if the serve button is pressed, start the ball moving
if(serveButton == 1){
ballInMotion = true;
}

//if the reset button is pressed, reset the scores and start the ball moving
if(resetButton == 1){
leftScore = 0;
rightScore = 0;
ballInMotion = true;
}

//print the scores
text(leftScore, fontSize, fontSize);
text(rightScore, width-fontSize, fontSize);
}


//serialEvent メソッドがバッファがsetup()で行った、
//bufferUntil()によって設定された値になると
//自動的にProcessing Sketchによって発動する(意味不明だ)

void serialEvent(Serial myPort){
//read the serial buffer
String myString = myPort.readStringUntil(linefeed);

//if you got any bytes other than the linefeed
if(myString !=null){
myString = trim(myString);

//カンマのところでstringを区切り、それらを整数に変える
int sensors[] = int(split(myString, ','));
//if you received all the sensor strings, use them
if(sensors.length ==4){
//calculate the flex sensors' ranges
float leftRange = leftMaximum - leftMinimum;
float rightRange = rightMaximum - rightMinimum;

//scale the flex sensors' results to the paddles' range
leftPaddle = height * (sensors[0]-leftMinimum)/leftRange;
rightPaddle = height * (sensors[1]-rightMinimum)/rightRange;

//assign the switches' values to the button variables
resetButton = sensors[2];
serveButton = sensors[3];

//print the sensor values
print("left:" + leftPaddle + "\tright:" + rightPaddle);
println("\treset:"+ resetButton + "\tserve:"+ serveButton);
}
}
}

void animateBall(){
//if the ball is moving left
if(xDirection < xdirection =" -xDirection;">= (rightPaddleX + ballSize/2))){
//if the ball is in between the top and bottom of the right paddle
if((rightPaddle - (paddleHeight/2) <= yPos) && (yPos <= rightPaddle + (paddleHeight/2))){ //reverse the horizontal direction: xDirection = -xDirection; } } } // if the ball goes off the screen left if(xPos <> width){
leftScore++;
resetBall();
}
//stop the bal going off the top or the bottom ofthe screen;
if((yPos - ballSize/2 <= 0)||(yPos + ballSize/2 >= height)){
//reverse the y direction of the ball
yDirection = -yDirection;
}
//update the ball position
xPos = xPos + xDirection;
yPos = yPos + yDirection;


//Draw the ball
rect(xPos, yPos, ballSize, ballSize);
}

void resetBall(){
//put the ball back in center
xPos = width/2;
yPos = height/2;
}

2008年5月28日水曜日

Processingかいています

utanoです。
とりあえず64ページまで作りこみました。

最初に書いたコードをちょこちょこいじっていくという形で本は進みます。
で、ちなみに本の後ろのAppendix Cに
コードが全文きれいにもう書かれた状態のものがあります。
そのなかで、設定で気をつけるといいかなぁと思った事を書きます。
もぅ分かりきってたらすみません。

Processingコード書くときのsetup()の中で:

println(Serial.list());
//シリアルポートを全部リストアップする

myPort = new Serial(this, Serial.list()[1], 9600);println(Serial.list());
//Arduinoをつなげているシリアルポートナンバーがあてられているリストの番号を[]に入れてmyPortとする

myPort.bufferUntil(linefeed);

となっていると思います。
全部コード書き終えて実行してみると、Serial.list()によりポートのリストアップを行います。
で、下の黒い部分に

[0]COM3
[1]COM4

とか表示されます。これはパソコンのポートを挙げてくれているのです。
で、自分がArduinoを挿しているシリアルの番号が例えばCOM4だったら、
リストにあるようにCOM4は[1]だったので

myPort = new Serial(this, Serial.list()[1], 9600);println(Serial.list());

[ ]内に1を入れるということになっています。

はい、茶番でしたー。ひきつづき頑張ります。