// Logana_revA3 Processing3 2021-10-30
import controlP5.*;
import java.util.*;
import processing.serial.*;
ControlP5 cp5;
ScrollableList[] SL = new ScrollableList[5];
RadioButton[] RB = new RadioButton[3];
Toggle[] TG = new Toggle[3];
Toggle bt;
Serial myPort = null; // シリアルポート
List<String> portList;
CColor bc = new CColor();
CColor fc = new CColor();
String RxStr = ""; // 受信中の文字列
String waveStr = ""; // 描いている文字列
boolean indON = false; // トリガインディケータ
boolean isDataRxing = false; // データ文字列受信中
boolean rptON = false; // 連続モード
boolean nonTrg = false; // 「トリガなし」出力
boolean cursors = false; // 「cursors」出力
boolean dragging = false; // ドラグ中か
int pntTrg = 100; // トリガ位
int runMode = 0; // 単発 連続
float zoomX = 1.0; // スクリーン倍率
int sampRate = 5; // サンプルレート
int repeetTimeUp; // 連続実施までの時間
// 定数の定義 ----------------------------
final int sSpeed = 115200; // シリアル通信速度
// データ描画用スクリーン位置定数
//final int srnLeft = 40;
final int srnLeft = 40;
final int srnTop = 200;
//final int srnWidth = 550;
final int srnWidth = 512;
final int srnHight = 160;
final int srnRight = srnLeft + srnWidth;
final int srnBottom = srnTop + srnHight;
// コントロール枠位置定数
final int crlTop = 50;
final int ctlTrgLeft = 10;
final int ctlAquLeft = ctlTrgLeft+200;
final int ctlRunLeft = ctlAquLeft+200;
// スクロールバー定数
final int BarL = srnLeft;
final int BarT = srnBottom+2;
final int BarW = srnWidth;
final int BarH = 20;
final int BarR = BarL+BarW;
final int BarB = BarT+BarH;
final int wBarT = BarT+1;
final int wBarH = BarH-2;
// アクティブウインドバー定数
int wBarL = srnLeft;
int wBarW = srnWidth/2;
int wBarR = wBarL+wBarW;
int fBar = 2; // Barの縮尺
// データポインタ
int dStart = 0; // 描き始める受信データ位置
int dEnd = srnWidth; // 描き終わる受信データ位置
int dStep = 1; // 描く受信データ間隔
int sStep = 1; // 描くスクリーン間隔
//カーソルライン位置(データ座標)
int posCurDL = pntTrg;
int posCurDR = pntTrg;
final color cGray = color(128);
final color cBlk = color(0);
final color cWit = color(255);
final color cRed = color(255,0,0);
final color cGrn = color(0,255,0);
final color cRed_r = color(0,255,255);
final color cGrn_r = color(255,9,255);
color cStr = cWit;
color cActBtn = color(50,150,240);
color cBgGroup = cBlk;
color cDataLine = cGrn;
color cActRun = color(150,100,0);
color cBakRun = color(0,100,0);
color cForRun = color(0,127,0);
color cTrig = cRed;
color cIndOn = cRed;
color cIndOff = cBlk;
color cBgBtn = color(80);
color cFgBtn = cGray;
color cBkGnd = color(50);
color cCursX = color(110,170,255);
color cCursY = color(255,140,255);
final List<String> trgList = Arrays.asList(
"*", "1", "0", "/", "\");
final List<String> sampList = Arrays.asList(
" 1 us ( 1MHz)"," 2 us (500kHz)",
" 5 us (200kHz)"," 10 us (100kHz)",
" 20 us ( 50kHz)"," 50 us ( 20kHz)",
"100 us ( 10kHz)","200 us ( 5kHz)",
"500 us ( 2kHz)"," 1 ms ( 1kHz)");
final String[][] strDiv = {
{"100us","200us","500us", "1ms", "2ms",
"5ms", "10ms", "20ms", "50ms","100ms"},
{ "50us","100us","250us", "500us", "1ms",
"2.5ms", "5ms", "10ms", "25ms", "50ms"},
{ "25us", "50us","125us", "250us","500us",
"1.25ms","2.5ms", "5ms","12.5ms", "25ms"}};
final int[] usPerDot = {
1,2,5,10,20,50,100,200,500,1000};
void setup() {
size(570, 430);
cp5 = new ControlP5(this);
cp5.setColorBackground(cBgBtn); // 明るく見やすく
PFont myFont = createFont("Verdana",12);
ControlFont cf1 = new ControlFont(myFont);
textFont(myFont);
cp5.setFont(cf1);
portList = Arrays.asList(Serial.list());
int portIndex = portList.size()-1;
// 各CHのトリガ条件の設定:( name, x, y, width, height )
for(int i=3;i>0;i--){
SL[i] = cp5.addScrollableList(
"CH"+i,ctlTrgLeft+40,crlTop+(i*25),50,120)
.setBarHeight(20) .setItemHeight(20)
.addItems(trgList).setValue(0);
}
SL[1].setValue(3);
// ポート選択の設定 ( name, x, y, width, height )
SL[0] = cp5.addScrollableList(
"portSelect",20,20,220,160)
.setBarHeight(20).setItemHeight(20)
.addItems(portList).setValue(portIndex);
// トリガと収集データの相対位置の設定ボタン
RB[0] = cp5.addRadioButton(
"r1SampPos",ctlAquLeft+50,crlTop+50)
.setSize(15,15).setColorLabel(cStr)
.setItemsPerRow(1).setSpacingColumn(100)
.addItem("トリガの後方",0)
.addItem("トリガの前後",4)
.addItem("トリガの前方",5)
.activate(0);
// サンプルレートの設定
SL[4] = cp5.addScrollableList(
"srSampRate",ctlAquLeft+25,crlTop+25,150,220)
.setBarHeight(20).setItemHeight(20)
.addItems(sampList).setValue(5);
// RUN/STOPボタンの設定:( name,初期値 )
bt = cp5.addToggle("btnRun",false)
.setPosition(ctlRunLeft+20,crlTop+15).setSize(90,30)
.setColorActive(cActRun) // ON色
.setColorBackground(cBakRun) // OFF色
.setColorForeground(cForRun); // マウス選択色
bt.setCaptionLabel("RUN").getCaptionLabel()
.align(ControlP5.CENTER, ControlP5.CENTER);
// 単発/連続のラジオボタン
RB[1] = cp5.addRadioButton(
"r2RunMode",ctlRunLeft+20,crlTop+60)
.setSize(15,15).setColorLabel(cStr)
.setItemsPerRow(2).setSpacingColumn(40)
.addItem("単発",0).addItem("連続",1)
.activate(0);
// トリガなしのボタン
TG[0] = cp5.addToggle("nonTrg",false)
.setPosition(ctlRunLeft+20,crlTop+85).setSize(15,15)
.setCaptionLabel("トリガなし");
// カーソルOnOffボタン
TG[1] = cp5.addToggle("cursors",false)
.setPosition(135,srnTop-20).setSize(15,15)
.setCaptionLabel("Cursors");
// 背景色変更ボタン
TG[2] = cp5.addToggle("whiteBack",false)
.setPosition(ctlRunLeft+80,20).setSize(15,15)
.setCaptionLabel("色 反転");
for(Toggle t:TG){
t.setColorLabel(cStr).getCaptionLabel()
.align(ControlP5.RIGHT_OUTSIDE, ControlP5.CENTER)
.toUpperCase(false) .setPaddingX(5)
;
}
// スケールのラジオボタン
RB[2] = cp5.addRadioButton("rbZoom",50,400)
.setSize(15,15).setColorLabel(cStr)
.setColorLabel(cStr)
.setItemsPerRow(3).setSpacingColumn(40)
.addItem(".5x",0)
.addItem("1x",1)
.addItem("2x",2)
.activate(1);
}
void draw() {
// 連続モードの処理を行う
if(rptON){
// 繰り返し時間になったら
if(repeetTimeUp < millis()){
btnRun(true); // RUNボタンを押す
rptON = false; // データ受信を待つ
}
}
background(cBkGnd);
drawScreen(); // 背景画面 描画
drawData(); // データ線 描画
indControl(); // 受信ライト 処理
drawCursor(); // カーソル 描画
}
// ================================
// 画面背景を描く width height
// ================================
void drawScreen(){
// ウインド枠を灰色にする
stroke(cGray);
fill(cBkGnd);
rect(1,1,width-2, height-2);
// データスクリーン ---------------------
stroke(cGray); // 枠を灰色に
fill(cBgGroup);
rect(srnLeft+1,srnTop+1,srnWidth,srnHight);
// ch番号及び data GND level-------------
stroke(cGray);
fill(cStr);
textSize(12);
int j = 1;
for(int vPos=srnTop+30;vPos<srnBottom;vPos+=30){
text("Ch"+j++,srnLeft-32,vPos-5);
line(srnLeft,vPos,srnRight,vPos);
}
// 小目盛は、10dot毎
stroke(cGray); //
int scaleStart = srnLeft+10-(dStart*sStep%10);
for(int i=scaleStart;i<srnRight;i+=10){
line(i,srnTop,i,srnTop+5);
line(i,srnBottom,i,srnBottom-5);
}
// 大目盛は、50dot毎
scaleStart = srnLeft+50-(dStart*sStep%50);
for(int i=scaleStart;i<srnRight;i+=50){
line(i,srnTop,i,srnBottom);
}
// スクロール Bar -------------------
stroke(cGray); // 枠の色
fill(cBgGroup); // 外ウインドの色
rect(BarL,BarT,BarW,BarH); // 外ウインド描く
fill(cBkGnd); // 内ウインドの色
rect(wBarL,wBarT,wBarW,wBarH); // 内ウインド描く
// コントロール枠 -------------------------
stroke(128); // 枠を灰色に
fill(cBgGroup);
//rect(10,crlTop,260,110,10);
rect(ctlTrgLeft,crlTop,190,110,10);
rect(ctlAquLeft,crlTop,190,110,10);
rect(ctlRunLeft,crlTop,140,110,10);
// コントロール枠内ラベル ---------------------
fill(cStr);
textSize(12);
text("<トリガ条件>",ctlTrgLeft+5,crlTop+18);
text("Ch1",ctlTrgLeft+8,crlTop+40);
text("Ch2",ctlTrgLeft+8,crlTop+65);
text("Ch3",ctlTrgLeft+8,crlTop+90);
text("*:なし", ctlTrgLeft+120,crlTop+30);
text("1:Hi", ctlTrgLeft+120,crlTop+46);
text("0:Low", ctlTrgLeft+120,crlTop+62);
text("/:立上り",ctlTrgLeft+120,crlTop+78);
text("\:立下り",ctlTrgLeft+120,crlTop+94);
text("<サンプル条件>",ctlAquLeft+5,crlTop+18);
// トリガ線を引く -------------------
vLine(cTrig, datX_appX(pntTrg));
// Div時間の表示 -------------------
String str;
str = strDiv[int(zoomX)][sampRate] + " / Div";
fill(cStr);
textSize(12);
text(str,srnLeft,srnTop-7);
fill(cGray);
text("211030 IWA",470,420);
}
// スクリーンに縦線を引く
void vLine(color c, int p){
if(p == 0) return;
stroke(c);
line(p,srnTop,p,srnBottom);
}
// +++++++++++++++++++++++++++++++++
// 座標変換 データ座標 ー> アプリ座標
// 受信データの位置を作画のための座標に
// +++++++++++++++++++++++++++++++++
int datX_appX(int dX){
int num = srnLeft + int((float)(dX - dStart) * zoomX);
if(num <= srnLeft) return 0;
if(num >= srnRight) return 0;
return num;
}
// +++++++++++++++++++++++++++++++++
// 座標変換 アプリ座標 ー> データ座標
// 作画のための座標を受信データの位置に
// +++++++++++++++++++++++++++++++++
int appX_datX(int aX){
return int(float(aX - srnLeft)/zoomX)+dStart;
}
// データ線 描画 +++++++++++++++++++++++++++++
// waveStrを一文字ずつデータ線に書いていく
//++++++++++++++++++++++++++++++++++++++++++
void drawData(){
int xPos; // 描いている現データのX座標
int dataNow; // 処理している 現データ
int dataNext; // 次に処理する 次データ
int diffData; // 現データと次データの変位
int ch; // 描いているチャネル
int testBit; // 上記のチャネルbit位置
int HiPos; // 上記のチャネルHiレベル描画位置
int LoPos; // 上記のチャネルLowレベル描画位置
// 各データの数だけ繰り返す ----------------------------
int endPos = (waveStr.length())-2;
if(endPos>dEnd)endPos = dEnd; //
xPos = srnLeft+int(zoomX);
for (int i=dStart;i<endPos;i+=dStep){
// データ毎の初期設定
// testBitをCh1を示すBit位置に戻す
// 文字列から必要データを抜き出し、bit値に直す
// 次のデータとのLogic変位を計算
testBit = 1;
dataNow = int(waveStr.charAt(i)) & 0x1F;
dataNext = int(waveStr.charAt(i+dStep)) & 0x1F;
diffData = dataNow ^ dataNext;
// 各チャネルの描画 5Ch分繰り返す ---------------------
stroke(cDataLine);
for (ch = 0; ch < 5; ch++){
// Logic Hi Low の画描位置を計算
HiPos = ch*30+10+srnTop;
LoPos = HiPos + 20;
// 現在のレベル位置に横線を引く
if ((dataNow & testBit) == 0)
line(xPos,LoPos,xPos+1,LoPos);
else
line(xPos,HiPos,xPos+1,HiPos);
// 次のデータのレベルが変位していれば、縦線を引く
if ((diffData & testBit) != 0)
line(xPos + sStep,HiPos,xPos + sStep,LoPos);
testBit <<= 1; // 次のチャンネル準備
} // 次のチャンネルへ
xPos += sStep; // 次のデータ描画位置
} // 次のデータへ
}
// 受信ライト 処理 ++++++++++++++++++++++++++++
// indON の値に従い受信ライト On/Off
//++++++++++++++++++++++++++++++++++++++++++++
void indControl() {
stroke(80);
if(indON) fill(cIndOn);
else fill(cIndOff);
circle(ctlRunLeft+120,crlTop+30, 10);
}
// =========================================
// カーソルを描く
// =========================================
void drawCursor(){
if(!cursors) return; // カーソル Off なら復帰
String str;
int nX,nY;
// カーソル線の表示
vLine(cCursX, datX_appX(posCurDL));
vLine(cCursY, datX_appX(posCurDR));
// カーソル数値を表示
fill(cCursY);
nY = timeToTrg(posCurDR);
str = "Y = " + usms(nY);
text(str,srnLeft+280,srnTop-7);
fill(cCursX);
nX = timeToTrg(posCurDL);
str = "X = " + usms(nX);
// X-Y の間隔を表示
text(str,srnLeft+180,srnTop-7);
str = "|X-Y| = " + usms(abs(nX-nY));
str += hzkhz(abs(nX-nY));
text(str,srnLeft+380,srnTop-7);
}
// カーソル位置からトリガまでの時間usを計算
int timeToTrg(int num){
return (num - pntTrg) * usPerDot[sampRate];
}
// 数値を us/msで表示
String usms(int num){
String str = "";
int aN = abs(num);
if(aN >= 100000){
str = nf(float(num)/1000,0,0)+" ms";
}else if(aN >= 10000){
str = nf(float(num)/1000,0,1)+" ms";
}else if(aN >= 1000){
str = nf(float(num)/1000,0,2)+" ms";
}else{
str = nf(num,0)+" us";
}
return str;
}
// 数値を hz/khzで表示
String hzkhz(int num){
if(num==0)return " (-- Hz)";
String str = " (";
float fnum = 1000000/float(num);
if(fnum >= 1000){
str += nf(fnum/1000,0,2)+" kHz)";
}else if(fnum >= 100){
str += nf(int(fnum),0)+" Hz)";
}else{
str += nf(fnum,0,1)+" Hz)";
}
return str;
}
// ================================
// シリアルポートが選択された時
// ================================
void portSelect(int n) {
// 既に接続されていれば、切断して
// 新しい選択項目は、index n で接続する
if ( myPort != null ) myPort.stop();
myPort = new Serial(this, portList.get(n), sSpeed);
myPort.bufferUntil('\n');
}
// ================================
// シリアル受信した時
// ================================
void serialEvent(Serial port) {
// 受信データがあれば、内容を確認して処理
if ( port.available() > 0 ) {
String str = port.readString();
str = trim(str);
if (str != null ){
// PIC側送信完了なら ---------------
if (str.equals("##")){
waveStr = RxStr; // 受信列を波形列とする
indON = false; // 受信ライト OFF
isDataRxing = false; // 受信中を 否
if(runMode==0){ // 単発なら
rptON = false; // rptONを 否
bt.setValue(0); // ボタン緑へ
}else{ // 連続なら
// 連続なら、500ms後に再びRUN操作をする
// ために、repeetTimeUp を設定
repeetTimeUp = millis()+500;
rptON = true; // rptONを 真
}
// PIC側コマンド正常受信なら ---------------
}else if (str.equals("#")){
RxStr = ""; // 受信列をクリア
isDataRxing = true; // 受信中を 真
// PIC側コマンドエラー受信なら ---------------
}else if (str.equals("!")){
RxStr = "";
// PIC側STOP受信なら ---------------
}else if (str.equals("!!")){
RxStr = "";
// PIC側のデータを受信した ---------------
}else if (isDataRxing){
indON = true; // 受信ライト OFF
RxStr += str; // 受信列に追加
}
}
}
}
// +++++++++++++++++++++++++++++++++
// RUN/STOPボタンを押した時
// +++++++++++++++++++++++++++++++++
void btnRun(boolean theFlag) {
String cmdStr = "";
// RUNボタンを押した時
if(theFlag) {
//waveStr = "";
String cmdSamp,cmdTrg;
bt.setCaptionLabel("STOP");
cmdSamp = str((int)SL[4].getValue());
cmdTrg = str((int)RB[0].getValue());
cmdStr = "#"
+ str((int)SL[1].getValue())
+ str((int)SL[2].getValue())
+ str((int)SL[3].getValue());
if(cmdStr.equals("#000"))cmdTrg="3";
if(nonTrg)cmdTrg = "3";
switch(cmdTrg){
case "0":pntTrg = 100;break;
case "3":pntTrg = 0;break;
case "4":pntTrg = 550;break;
case "5":pntTrg = 1000;break;
}
cmdStr += "#"+cmdSamp+cmdTrg+"\n" ;
}
// STOPボタンを押した時
else {
rptON = false;
bt.setCaptionLabel("RUN");
if (isDataRxing){
cmdStr = "!";
}
}
if(cmdStr != ""){
//if(false){
try{
myPort.write(cmdStr);
}
catch(Exception e) {
//msg("シリアル通信エラー");
myPort.stop();
}
}
}
// サンプルレート変更 +++++++++++++++++++
// サンプルレートを変更した時、
// リスト項目の背景を少し明るく見やすく
// +++++++++++++++++++++++++++++++++++
void srSampRate(int n) {
waveStr = ""; //
posCurDL = pntTrg; // カーソルのリセット
posCurDR = pntTrg;
bc.setBackground(cBgBtn);
fc.setBackground(cFgBtn);
// 古い選択項目の背景を戻し、新項目の背景を明るく
cp5.get(ScrollableList.class, "srSampRate")
.getItem(sampRate).put("color", bc);
sampRate = n;
cp5.get(ScrollableList.class, "srSampRate")
.getItem(sampRate).put("color", fc);
}
// +++++++++++++++++++++++++++++++++
// サンプル位置を変更した時
// 非選択にならないよう処置
// +++++++++++++++++++++++++++++++++
void r1SampPos(int num) {
if(num < 0){ // 非選択(-1)なら
RB[0].activate(0); // Item 0 を選択
RB[0].setValue(0);
}
}
// +++++++++++++++++++++++++++++++++
// 単発/連続を変更した時
// +++++++++++++++++++++++++++++++++
void r2RunMode(int num) {
if(num < 0){
RB[1].activate(0);
RB[1].setValue(0);
runMode = 0;
}else{
runMode = num;
}
}
// +++++++++++++++++++++++++++++++++
// 倍率を変更した時
// +++++++++++++++++++++++++++++++++
void rbZoom(int num) {
if(num < 0){
RB[2].activate(1);
RB[2].setValue(1);
num = 1;
}
wBarL = 40;
switch(num){
case 0: // x0.5
wBarW = srnWidth;fBar = 1;
dStep = 2; sStep = 1;
zoomX = 0.5;
break;
case 1: // x1
wBarW = srnWidth/2;fBar = 2;
dStep = 1; sStep = 1;
zoomX = 1.0;
break;
case 2: // x2
wBarW = srnWidth/4;fBar = 2;
dStep = 1; sStep = 2;
zoomX = 2.0;
break;
}
dStart = (wBarL-BarL)*fBar;
dEnd = (wBarW- 1) * 2 + dStart;
}
// +++++++++++++++++++++++++++++++++
// 背景色を変更した時に実行
// +++++++++++++++++++++++++++++++++
void whiteBack(boolean theFlag) {
if(theFlag==true) { // 白 背景を選択
cStr = cBlk;
cActBtn = color(205,105,15);
cBgGroup = cWit;
cDataLine = cGrn_r;
cActRun = color(105,155,255);
cBakRun = color(255,155,255);
cForRun = color(255,128,255);
cTrig = cRed_r;
cIndOn = cRed_r;
cIndOff = cWit;
cBgBtn = color(175);
cBkGnd = color(205);
cCursX = color(145,85,0);
cCursY = color(0,115,0);
} else { // 黒 背景を選択
cStr = cWit;
cActBtn = color(50,150,240);
cBgGroup = cBlk;
cDataLine = cGrn;
cActRun = color(150,100,0);
cBakRun = color(0,100,0);
cForRun = color(0,127,0);
cTrig = cRed;
cIndOn = cRed;
cIndOff = cBlk;
cBgBtn = color(80);
cFgBtn = cGray;
cBkGnd = color(50);
cCursX = color(110,170,255);
cCursY = color(255,140,255);
}
cp5.setColorActive(cActBtn) // ON色
.setColorBackground(cBgBtn) // OFF色
.setColorForeground(cActBtn); // OFF色
for(ScrollableList s:SL){
s.setColorLabel(cStr)
.setColorValue(cStr);
}
for(RadioButton r:RB)r.setColorLabel(cStr);
for(Toggle t:TG) t.setColorLabel(cStr);
bt.setColorActive(cActRun) // ON色
.setColorBackground(cBakRun) // OFF色
.setColorForeground(cForRun) // マウス選択色
.setColorLabel(cStr);
bc.setBackground(cBgBtn);
fc.setBackground(cFgBtn);
for(int i=0;i<10;i++){
SL[4].getItem(i).put("color", bc);
}
SL[4].getItem(sampRate).put("color", fc);
}
// マウスプレス ++++++++++++++++++++++++
// カーソルの位置を決める
// +++++++++++++++++++++++++++++++++++
void mousePressed(MouseEvent e){
// データスクリーン上か
if(cursors && isInSrn()){
if( e.getButton() == LEFT ){
// println( "左が押された" );
posCurDL = appX_datX(pmouseX);
} else if( e.getButton() == RIGHT ){
// println( "右が押された" );
posCurDR = appX_datX(pmouseX);
}
}
}
// マウスドラッグ +++++++++++++++++++++++
// Barをドラッグしたら、その移動量だけ
// Barを移動させる
//++++++++++++++++++++++++++++++++++++
void mouseDragged(MouseEvent e){
//スクロールバーをドラッグした場合
if(mouseX == pmouseX)return;
if((ptrInBar()==1)| dragging){
dragging = true;
wBarL += mouseX - pmouseX;
if(wBarL<BarL)wBarL=BarL;
if(wBarL>BarR-wBarW)wBarL=BarR-wBarW;
// 波形データの描く範囲を計算
dStart = (wBarL-BarL)*fBar;
dEnd = (wBarW- 1) * 2 + dStart;
}
}
// マウスリリース ++++++++++++++++++++++
// Barをドラッグ中に、Barエリアから外れても
// 処理を継続できるように追加
// +++++++++++++++++++++++++++++++++++
void mouseReleased(MouseEvent e){
dragging = false;
}
// マウスポインター位置確認 ++++++=++++++=
// Mouse Pointer が
// ScrollBarの外側なら :0
// ActiveWindowBarの内側なら :1
// ScrollBarの左背景なら :2
// ScrollBarの右背景なら :3
// +++++++++++++++++++++++++++=++++++=
int ptrInBar(){
if(pmouseX < BarL)return 0;
if(pmouseX > BarR)return 0;
if(pmouseY < BarT)return 0;
if(pmouseY > BarB)return 0;
if(pmouseX < wBarL)return 2;
if(pmouseX > (wBarL+wBarW)) return 3;
return 1;
}
// マウスポインター位置確認 ++++++=++++++=
// Mouse Pointer が
// データスクリーンの外側なら :false
// 内側なら :true
// +++++++++++++++++++++++++++=++++++=
boolean isInSrn(){
if(pmouseX < srnLeft) return false;
if(pmouseX > srnRight)return false;
if(pmouseY < srnTop) return false;
if(pmouseY > srnBottom)return false;
return true;
}