1. 程式人生 > >Processing摸索前行(7)

Processing摸索前行(7)

上一篇,我們經過摸索已經掌握了示波器的靜態圖形繪製的方法,這裡我們繼續前行,將其動態波形的功能實現。
從現實情況來看,動態波形一定是數字一邊產生一邊繪製到螢幕上,而不是一開始就有一堆的資料等著我們用。

這裡估計就要用到類似執行緒之類的概念來操作了《Processing摸索前行(6)-在processing中實現多執行緒》,而我們在Processing中沒有thread的概念,沒有類,所以我們不得不另求他法了,經過反覆摸索,發現有一個封裝的函式可以說實現這樣的功能,這個函式的名稱就是registerMethod,這是一個註冊方法的函式,我們就利用他註冊一個post函式,熟悉VC執行緒的人一定看到它就知道大概意思了,它是負責推送訊息的。這個註冊函式在Processing的官方reference中沒有提到,但實際是可以用的。

有了它,我們的事情就好辦多了,可以理解為我們用它來產生資料也可以理解為用它來獲取資料,下面我們來看看程式碼的實現:

   import processing.serial.*;

Serial sp;
int x1,x2;
int w=720;
int h=380;
int woff=80;
int hoff=80;
FloatList wav1data;
FloatList wav2data;
int rate=1;
float tempdata=0;

void settings() {
 
  size(w,h);

}

void setup()
{
   
    sp=new Serial(this,"COM5",9600);
    frameRate(rate);
    registerMethod("post", this);
    wav1data= new FloatList();
    wav2data= new FloatList(); 
    x1=0;
    x2=-80;      

}



void draw()
{
  
    

    // 繪製背景
     drawBg();
    //繪製波形
    drawWave(); 
  
  
  
}


 void post() 
 {
      
      
        readData();
        //genData();
        //println(wav1data.size());
        println("--------------------"+x1+"-------------------");

}

 void readData()
 {
     while(sp.available()>0)
            {
              tempdata=sp.read();
              //if(tempdata!=0)
              //{
              wav1data.append(tempdata);
              println("value :"+tempdata);
            //}
              println(wav1data.size());
         
         if(wav2data.size()>1440)
         {
           wav1data.remove(0);
         }
        }
 }



 void  genData()
 {
   //獲取資料並存儲,每次產生或者清除1個周波
       for(int i=0;i<360;i++)
       {
            if(wav1data.size()<720)
            {
              if(random(-20,8)>7)
              wav1data.append(h/2+80*sin(i*PI/180)-random(10));
              else if(random(0,50)<1)
              wav1data.append(h/2+80*sin(i*PI/180)+random(10));
              else
               wav1data.append(h/2+80*sin(i*PI/180));
              wav2data.append(h/2+80*sin(i*PI/180));
            }
       
        if(wav1data.size()>720)
       {
          
           wav1data.remove(i);
           wav2data.remove(i);
        
       }

   }


 }
 
 
  void drawBg()
  {
  
   background(0);
  Pline ln1=new Pline(0,40,w,40);
  for(int i=0;i<w/woff;i++)
      ln1.offsetLine(0,woff);
     
  Pline ln2=new Pline(40,0,40,h);
  for(int i=0;i<w/hoff;i++)
     ln2.offsetLine(hoff,0);
     
   //水平標尺  
   Pline ln3=new Pline(0,h/2+2,0,h/2+8);
   Pline ln4=new Pline(0,h/2+10,0,h/2+4);
   ln3.changeColor(color(20,220,20));
   ln4.changeColor(color(20,220,20));
   for(int i=0;i<w/40;i++)
  {
     ln3.offsetLine(40,0);
     for(int j=0;j<10;j++)
      ln4.offsetLine(4,0);
  }
   
   //垂直標尺
     Pline ln5=new Pline(w/2,0,w/2+8,0);
   Pline ln6=new Pline(w/2,0,w/2+4,0);
   ln3.changeColor(color(20,220,20));
   ln4.changeColor(color(20,220,20));
   for(int i=0;i<w/40;i++)
  {
     ln5.offsetLine(0,40);
     for(int j=0;j<10;j++)
      ln6.offsetLine(0,4);
  }  

}



void drawWave()
{
        println("*************start drawing*******************"+wav1data.size());
        stroke(60,60,150);      
        for(int a=0;a<wav1data.size()-1;a++) 
        {
        line(x1,wav1data.get(a),x1-1,wav1data.get(a+1));
        println(x1+" :"+wav1data.get(a)+"      "+(x1+1)+" :"+wav1data.get(a+1));
         x1=x1%w+1;
        }
    
    stroke(150,10,10);   
    for(int a=0;a<wav2data.size()-1;a++) 
    {
    line(x2,wav2data.get(a),x2+1,wav2data.get(a+1));
    println(x2+" :"+wav2data.get(a)+"      "+(x2+1)+" :"+wav2data.get(a+1));
    x2=x2%w+1;
    }

}

 class Pline
{
  float StartX,StartY,EndX,EndY;
  float Alf=254;
  
   color Color= color(0,180,0);
   Pline(float sx,float sy,float ex,float ey)
   {
     StartX=sx;
     StartY=sy;
     EndX=ex;
     EndY=ey;
     drawline();
   }
   
    Pline(float sx,float sy,float ex,float ey,float alf )
   {
     StartX=sx;
     StartY=sy;
     EndX=ex;
     EndY=ey;
     Alf=alf;
     drawline();
   }
   
      Pline(float sx,float sy,float ex,float ey,color clr )
   {
     StartX=sx;
     StartY=sy;
     EndX=ex;
     EndY=ey;
     Color=clr;
     drawline();
   }
   
       Pline(Pline ln,color clr)
   {
     StartX=ln.StartX+20;
     StartY=ln.StartY+20;
     EndX=ln.EndX+20;
     EndY=ln.EndY+20;
     Color=clr;
     drawline();
   }
   
    Pline(float sx,float sy,float ex,float ey,color clr,float alf )
   {
     StartX=sx;
     StartY=sy;
     EndX=ex;
     EndY=ey;
     Color=clr;
     Alf=alf;
     drawline();
   }
   
    Pline(Pline ln,color clr,float alf )
   {
    StartX=ln.StartX+20;
     StartY=ln.StartY+20;
     EndX=ln.EndX+20;
     EndY=ln.EndY+20;
     Color=clr;
     Alf=alf;
     drawline();
   }
   
   void changeColor(color cl)
   {
      Color=cl;
   }
   
   void drawline()
   {
     stroke(Color,Alf);
     line(StartX,StartY,EndX,EndY);
     noStroke();  
   }
 
 
 void offsetLine(float offsetX,float offsetY)
 {
  
    StartX=StartX+offsetX;
     StartY=StartY+offsetY;
     EndX=EndX+offsetX;
     EndY=EndY+offsetY;
   drawline();
 }

}

執行效果如下:
在這裡插入圖片描述
上述程式碼分別實現了模擬資料的產生gendata函式以及讀取arduino串列埠函式readdata,這裡需要注意的是在arduino端的波特率不能設定太高,否則依靠中斷實現的串列埠通訊不能及時把資料送到processing中,那麼獨到的資料就會為0,也就不會有影象顯示。
以下是實際串列埠讀取的資料顯示的影象(這裡是依靠一個光敏電阻從A0口獲得的資料):
在這裡插入圖片描述
其中arduino端的程式相當的簡單,就一個串列埠傳送資料:

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
   Serial.write(analogRead(A0));
   delay(10);
}