チーム1443

課題名

光センサーを使ったアプリケーション

研究者名

2年14組24番 杉内 茜
2年14組25番 鈴川 馨亮

概要

光センサー(カドミウムセンサ)で受け取った光の強さをLCDに表示して、
その強さによってボールの加速度を変えるようにした。

AD変換で得た値を加速度に足していき、
ボールが画面の端(壁)にあたると跳ね返るようにしている。

また、LCDには得たアナログ値とそれに応じて変化する目盛りを表示させた。

使用機材


  • PSoC評価基板 CY3210 EVAL1
  • Miniprog書き込み器
  • 27443デバイス
  • 光センサー(カドミウムセンサ)
  • シリアル通信ケーブル
  • ジャンパー線 2本

PSoCでの処理

光センサーで光の強さを測定し、
AD変換した値をシリアルポートを使用して送信する。

・ブロック図
sensor_block1.png

ソースコードver1

import processing.serial.*;
Serial myPort;

final int width=640;
final int height=640;

int dataCountT=0;
int dataCountF=0;
String str = "1";


int r = 10;
float x0 = r, y0 = r;
float v = 30;
float theta = (PI/8)*3; //θ=3*π/8
float t = 0;
float a = 0.0; //
float x = x0, y = y0;
float vx = v * cos(theta), vy = v * sin(theta);

void setup(){
size(width,height);
myPort = new Serial(this,"COM3",38400);
colorMode(RGB,255,255,255,100); 
ellipseMode(RADIUS);  background(0,0,0); 
frameRate(30); 
}
void draw()
{
stroke( 0, 0, 0, 10 ); 
fill( 0, 0, 0, 10 ); 
rect( 0, 0, width, height ); 
x = x0 + vx*t + a*(vx/(vx*vx+vy*vy))*t*t/2; 
y = y0 + vy*t + a*(vy/(vx*vx+vy*vy))*t*t/2; 
stroke( 0, 0, 100, 100 ); 
fill( 0, 200, 255, 100 ); 
ellipse( x, y, 10, 10 ); 
//if(str.equals("Aa")){
//  a=1.0;
//}else if(str.equals("B")){
//  a=2.0;
//}else {
//  a=5.0;

a = a + Integer.parseInt(str);

//println(a);
t=t+0.1;
if( y > height-r){ 
vy = -vy;
x0 = x; 
y0 = height-r; 
t = 0; 
}else if(y<r){
vy = -vy; 
x0 = x; 
y0 = r; 
t = 0; 
}else if(x>width-r){
vx = -vx; //
x0 = width-r; 
y0 = y; 
t = 0; 
}else if(x<r){
vx = -vx; //x 
x0 = r; 
y0 = y; 
t = 0; 
}
}

void serialEvent(Serial p){

str = myPort.readString();
println(str);

println("UART:"+str);
}

ソースコードver2

import processing.serial.*;
Serial myPort;
final float g = 1;
final float f = 1;
float t = 0;
String str = "1";


int pmx,pmy;
ArrayList<Ball> b;
void setup(){
size(600,600);
 b = new ArrayList<Ball>();
 b.add(new Ball(b,0,width/2,height,30));
 myPort = new Serial(this,"COM3",38400);
}
void draw(){
background(0);
 for(int i=0; i<b.size(); i++){
   b.get(i).update();
 }
}
void mousePressed(){
pmx = mouseX;
 pmy = mouseY;
}
void mouseReleased(){
b.add(new Ball(b,pmx,pmy,(mouseX-pmx)/10,(mouseY-pmy)/10,30));
}

class Ball
{
float x,y;
 float vx = 1,vy = -15;
 float a = 0;
 float size;
 ArrayList<Ball> others;
 int id;
 color cl;
 Ball(ArrayList<Ball> o,int id,float x,float y,float size){
   others = o;
   this.id = id;
   this.x = x;
   this.y = y;
   this.size = size;
   setColor();
 }
 
 Ball(ArrayList<Ball> o,float x,float y,float vx,float vy,float size){
   others = o;
   id = o.size()+1;
   this.x = x;
   this.y = y;
   this.vx = vx;
   this.vy = vy;
   this.size = size;
   //色をセット
   setColor();
 }
 void setColor(){
   pushStyle();
   colorMode(HSB,100);
   cl = color(random(100),100,100);
   popStyle();
 }
 void update(){
   //移動
   move();
   //衝突判定
   bound();
   //描画
   display();
 }
 void display(){
   //ellipse(x,y,size,size);
   loadPixels();
   for(int i=0; i<width; i++){
     for(int j=0; j<height; j++){
       float distance = dist(x,y,i,j);
       if(distance > size*2)continue;//描画範囲
       int index = i+j*width;
       color c = pixels[index];
       float r = red(c)+size*size*red(cl)/(distance*distance*10);
       float g = green(c)+size*size*green(cl)/(distance*distance*10);
       float b = blue(c)+size*size*blue(cl)/(distance*distance*10);
       pixels[index] = color(r,g,b);
     }
   }
   updatePixels();
 }

 void move(){
   vy += g;//重力
   System.out.println(str);
   t += Integer.parseInt(str);
   //x += vx; 
   x =  vx*t; 
   y += vy;

  //壁との衝突判定
   if(x+size/2 > width){
     x = width-size/2;
     vx *= -f;
   }
   else if(x-size/2 < 0){
     x = size/2;
     vx *= -f;
   }
   if(y+size/2 > height){
     y = height-size/2;
     vy *= -f;
   }
   else if(y-size/2 < 0){
     y = size/2;
     vy *= -f;
   }
 }
   
 void bound(){
   for(int i=0; i<others.size(); i++){
     if(i == id)continue;
     Ball b = others.get(i);
     float distance = dist(x,y,b.x,b.y);//距離
     float minDist = size/2 + b.size/2;
     if(distance < minDist){
       float angle = atan2(b.y-y,b.x-x);
       float targetX = x+cos(angle)*minDist;
       float targetY = y+sin(angle)*minDist;
     }
   }
 }
}

void serialEvent(Serial p){

str = myPort.readString();
println(str);

println("UART:"+str);
}

考察

このプロジェクトは,光センサーとシリアル通信を応用させたものである.
光の強さをシリアル通信によりアプリケーション内の球の速さを加減するという仕様である.
アプリケーション単体としては予想した動きになったが,PSoCとのシリアル通信時に値の通信がうまく行えず期待した動作が得られなかった.
改善としてPSoC側のメインプログラムから値を数段階に分けて球の速度を調整するしようにした.
アプリケーションの動きとしては壁から反射するときの球の動きが不自然になってしまったため,そこを工夫することによりより良いプロジェクトにできたと考えられる.

  • 最終更新:2014-10-21 17:32:45

このWIKIを編集するにはパスワード入力が必要です

認証パスワード