#include #include "HX711.h" #include //Core graphics library #include //Hardware-specific library #include #define LCD_RD A0 //LCD Read goes to Analog 0 #define LCD_WR A1 //LCD Write goes to Analog 1 #define LCD_CD A2 //Command/Data goes to Analog 2 #define LCD_CS A3 //Chip Select goes to Analog 3 #define LCD_RESET A4 //Can alternately just connect to Arduino's reset pin //#define CALIBRATION_X 110 //#define CALIBRATION_Y 76 const int DT_PIN1 = 25; //Arduinoの何番に入力したかを打ち込む const int SCK_PIN1 = 29; const int DT_PIN2 = 33; const int SCK_PIN2 = 37; const int DT_PIN3 = 41; const int SCK_PIN3 = 45; const int DT_PIN4 = 49; const int SCK_PIN4 = 53; static float gram1 = 0; //各ロードセルにかかる重さ(kg) static float gram2 = 0; static float gram3 = 0; static float gram4 = 0; static float ogram1 = 0;//1つ前に検知された重さ(kg)が入る ノイズをはじくのに使う static float ogram2 = 0; static float ogram3 = 0; static float ogram4 = 0; static int flg = 0; //メニュー画面から何を選ぶかで値が変わる static float ax; static float ay; static float az; HX711 Scale1; HX711 Scale2; HX711 Scale3; HX711 Scale4; #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define WHITE 0xFFFF #define YP A3 #define XM A2 #define YM 9 #define XP 8 #define TS_MINX 0000//補正プログラムで得たx座標の最小値を入れる #define TS_MAXX 1111//補正プログラムで得たx座標の最大値を入れる #define TS_MINY 2222//補正プログラムで得たy座標の最小値を入れる #define TS_MAXY 3333//補正プログラムで得たy座標の最大値を入れる #define STATUS_X 10 #define STATUS_Y 65 Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); TSPoint tp; unsigned long tim = 0; float xx = 0; float yy = 0; float xxx = 0; float yyy = 0; float xxxx = 0; float yyyy = 0; float idou = 0; int Maxx = 0; int Minx = 0; int Maxy = 0; int Miny = 0; int Maxz = 0; float cou1 = 0; float cou2 = 0; float cou3 = 0; float cou4 = 0; float cou5 = 0; float cou6 = 0; float cou7 = 0; float cou8 = 0; int cou9 = 0;//汎用の変数 int suu = 0; #define MINPRESSURE 100 #define MAXPRESSURE 2000 void setup() { //Serial.begin(115200);//シリアル通信時使用 Scale1.begin(DT_PIN1,SCK_PIN1); Scale2.begin(DT_PIN2,SCK_PIN2); Scale3.begin(DT_PIN3,SCK_PIN3); Scale4.begin(DT_PIN4,SCK_PIN4); tft.reset(); tft.begin(0x9341); /*使っている液晶パネルの型番ID?を()に入れる 0x9328 0x9325 0x4535 0x7575 0x8357 0x0101 0x8347 などがある模様*/ tft.fillScreen(WHITE); tft.setRotation(1); tft.setTextColor(BLACK); tft.setTextSize(3); tft.setCursor(52,38); tft.println("Weight Scale"); tft.setCursor(52,86); tft.println("Stabilometer"); tft.setCursor(27,134); tft.println("Dynamic Balance"); tft.setCursor(58,182); tft.println("Gait Safety"); //パラメータ設定 荷重されていないとき0を返すように調整している気がする Scale1.set_scale(2280.f); Scale2.set_scale(2280.f); Scale3.set_scale(2280.f); Scale4.set_scale(2280.f); Scale1.tare(); Scale2.tare(); Scale3.tare(); Scale4.tare(); } void loop(void) { gram1 = Scale1.get_units(1) * 6666;//別プログラムで調べた補正値を入れる gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; PORTD |= _BV(5); TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if(flg == 0) { if(((p.x > 710) && (p.x < 850)) && ((p.z > 300) && (p.z < MAXPRESSURE)))//体重計モード { while((flg < 10))//flgは1なので体重を表示し続ける { flg = 1; tft.fillScreen(WHITE); tft.setTextColor(BLUE); tft.setTextSize(4); tft.setCursor(70,105); gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; tft.print(gram1 + gram2 + gram3 + gram4); tft.println(" kg"); //体重は表示し続ける TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z < 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } if(((p.x > 580) && (p.x < 680)) && ((p.z > 300) && (p.z < MAXPRESSURE)))//重心動揺計モード { flg = 2; tft.fillScreen(WHITE); tft.setCursor(20,105); tft.println("Stand on a Board"); while((gram1 < 4) && (gram2 < 4) && (gram3 < 4) && (gram4 < 4))//ボードに人が乗っていないときはループさせて待つ { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; } tft.fillScreen(WHITE); tft.setCursor(78,105); tft.print("TOP LEFT"); while(gram3 < 20) { gram3 = Scale3.get_units(1) * 8888; } tft.fillScreen(WHITE); tft.setCursor(75,105); tft.print("TOP RIGHT"); while(gram2 < 20) { gram2 = Scale2.get_units(1) * 7777; } tft.fillScreen(WHITE); tft.setCursor(68,105); tft.print("BOTTOM LEFT"); while(gram4 < 30) { gram4 = Scale4.get_units(1) * 9999; } tft.fillScreen(WHITE); tft.setCursor(60,105); tft.print("BOTTOM RIGHT"); while(gram1 < 30) { gram1 = Scale1.get_units(1) * 6666; } tft.fillScreen(WHITE); tft.setCursor(65,105); tft.println("Stay Still"); delay(2000); tft.fillScreen(WHITE); ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; if((abs(gram1 - ogram1)) > 10) //10kg以上一気に重さが変わっていればノイズだと判断する { gram1 = ogram1; } if((abs(gram2 - ogram2)) > 10) { gram2 = ogram2; } if((abs(gram3 - ogram3)) > 10) { gram3 = ogram3; } if((abs(gram4 - ogram4)) > 10) { gram4 = ogram4; } ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; while((gram1 > 4) || (gram2 > 4) || (gram3 > 4) || (gram4 > 4))//センサーの値がどれか1つでも4kgを超えていれば人が乗っていると判断 { if(cou9 == 0) { delay(5000);//人がボードに乗ってから5秒待つ cou9 = 1; } if((xx == 0) && (yy == 0))//最初の1回だけ実行される { tim = millis();//データーの収集を始めた時間 suu = 1;//データ出力の回数 float x = (gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4)); float y = (gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4)); xx = x / 4444;//1つ前のx座標をcmに変換してxxに入れる//320÷センサーの横方向の距離(実際にメジャーとかで測ってください)でxを割る yy = y / 5555;//1つ前のy座標をcmに変換してyyに入れる//240÷センサーの縦方向の距離でyを割る Maxx = x;//x,yの最大値と最小値 Minx = x; Maxy = y; Miny = y; if((x < 160) && (y < 160))/*重心位置がどの座標面にあるか 重心は外果の前方にあるのでy座標を2:1に分ける点を前後の中心とした*/ { cou1 = cou1 + 1; } if((x >= 160) && (y < 160)) { cou2 = cou2 + 1; } if((x < 160) && (y >= 160)) { cou3 = cou3 + 1; } if((x >= 160) && (y >= 160)) { cou4 = cou4 + 1; } } else { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; if((abs(gram1 - ogram1)) > 10) //10kg以上一気に重さが変わっていればノイズだと判断する { gram1 = ogram1; } if((abs(gram2 - ogram2)) > 10) { gram2 = ogram2; } if((abs(gram3 - ogram3)) > 10) { gram3 = ogram3; } if((abs(gram4 - ogram4)) > 10) { gram4 = ogram4; } ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; //4つのセンサーの値から重心座標を求める float x = (gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4)); float y = (gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4)); int x1 = int(((((gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4))) - 160) * 3) + 160);//重心移動を分かりやすくするため3をかけた int y1 = int(((((gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4))) - 160) * 3) + 160); tft.fillCircle(x1,y1,3,BLACK); xxx = xxx + abs((x / 4444) - xx); yyy = yyy + abs((y / 5555) - yy); idou = idou + float(sqrt((pow(((x / 4444) - xx) , 2)) + (pow(((y / 5555) - yy) , 2))));//重心移動距離の計算 suu = suu + 1; xxxx = xxxx + ((x / 4444) + xx); yyyy = yyyy + ((y / 5555) + yy); if(Maxx < x) { Maxx = x; } if(Minx > x) { Minx = x; } if(Maxy < y) { Maxy = y; } if(Miny > y) { Miny = y; } if((x < 160) && (y < 160))/*重心位置がどの座標面にあるか 重心は外果の前方にあるのでy座標を2:1に分ける点を前後の中心とした*/ { cou1 = cou1 + 1; } if((x >= 160) && (y < 160)) { cou2 = cou2 + 1; } if((x < 160) && (y >= 160)) { cou3 = cou3 + 1; } if((x >= 160) && (y >= 160)) { cou4 = cou4 + 1; } xx = x / 4444; yy = y / 5555; } if((millis() - tim) > 30000) { tft.fillRect(160,0,2,240,RED); tft.fillRect(0,160,320,2,RED); delay(5000); //重心動揺データーを表示 tft.fillScreen(WHITE); tft.setTextSize(2); tft.setCursor(5,50); tft.print("Kyori");//重心移動距離 全体 x軸 y軸 tft.print(idou); tft.print("cm"); tft.print(" x"); tft.print(xxx); tft.print(" y"); tft.println(yyy); tft.setCursor(5,105); tft.print("Menseki");//矩形面積 tft.print(((Maxx - Minx) / 4444) * ((Maxy - Miny) / 5555)); tft.print("cm2 "); tft.print("x");//重心のx座標y座標の範囲 tft.print(Minx / 4444); tft.print("~"); tft.print(Maxx / 4444); tft.print(" y"); tft.print(Miny / 5555); tft.print("~"); tft.println(Maxy / 5555); tft.setCursor(5,160); tft.print("Zahyou");//重心位置の分布を座標面で表す tft.print((cou1 / (cou1 + cou2 + cou3 + cou4)) * 100); tft.print("% "); tft.print((cou2 / (cou1 + cou2 + cou3 + cou4)) * 100); tft.print("% "); tft.print((cou3 / (cou1 + cou2 + cou3 + cou4)) * 100); tft.print("% "); tft.print((cou4 / (cou1 + cou2 + cou3 + cou4)) * 100); tft.print("% "); tft.print("ave("); tft.print((xxxx / suu) - 17.85);//x座標の平均を出してセンサーの横間隔の1/2を引く tft.print(","); tft.print((yyyy / suu) - 17.73);//y座標の平均を出してセンサーの縦間隔の2/3を引く tft.print(")"); flg = 10; while(flg == 10)//重心動揺計測が終わったのでループさせる { TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z > 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } } } if(((p.x > 350) && (p.x < 450)) && ((p.z > 300) && (p.z < MAXPRESSURE)))//動的バランスモード { flg = 3; tft.fillScreen(WHITE); tft.setTextSize(3); tft.setCursor(110,105); tft.println("START"); gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; while((gram1 < 4) && (gram2 < 4) && (gram3 < 4) && (gram4 < 4))//ボードに人が乗っていないときはループさせて待つ { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; } gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; tft.fillScreen(WHITE); tft.setCursor(78,105); tft.print("TOP LEFT"); while(gram3 < 20) { gram3 = Scale3.get_units(1) * 8888; } tft.fillScreen(WHITE);//センサーがスリープしている可能性を考え荷重する tft.setCursor(75,105); tft.print("TOP RIGHT"); while(gram2 < 20) { gram2 = Scale2.get_units(1) * 7777; } tft.fillScreen(WHITE); tft.setCursor(68,105); tft.print("BOTTOM LEFT"); while(gram4 < 35) { gram4 = Scale4.get_units(1) * 9999; } tft.fillScreen(WHITE); tft.setCursor(60,105); tft.print("BOTTOM RIGHT"); while(gram1 < 35) { gram1 = Scale1.get_units(1) * 6666; } ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; cou9 = 1; tim = millis(); while((gram1 > 4) || (gram2 > 4) || (gram3 > 4) || (gram4 > 4))//センサーの値がどれか1つでも4kgを超えていれば人が乗っていると判断 { tft.fillScreen(WHITE); tft.fillRect(120,0,80,50,RED); tft.fillRect(120,190,80,50,RED); tft.fillRect(0,80,50,80,RED); tft.fillRect(270,80,50,80,RED); tft.fillRect(70,60,50,50,BLUE); tft.fillRect(200,60,50,50,BLUE); tft.fillRect(70,130,50,50,BLUE); tft.fillRect(200,130,50,50,BLUE); while(flg < 10) { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; if(cou9 == 1) { delay(2000);//人がボードに乗ってから2秒待つ cou1 = 0; cou2 = 0; cou3 = 0; cou4 = 0; cou5 = 0; cou6 = 0; cou7 = 0; cou8 = 0; cou9 = 0; tim = millis(); } if((gram1 < 4) && (gram2 < 4) && (gram3 < 4) && (gram4 < 4)) { tft.fillCircle(160,120,3,BLACK); } else { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; int x = int(((((gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4))) - 160) * 1.4) + 160);//課題の難易度を下げるため1.4をかけた int y = int(((((gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4))) - 160) * 4) + 160);//課題の難易度を下げるため色々した tft.fillCircle(x,y,3,BLACK); if(((x >= 120) && (x <= 200) && (y >= 0) && (y <= 50)) && (cou1 == 0)) { tft.fillRect(120,0,80,50,WHITE); cou1 = cou1 + 1; } if(((x >= 120) && (x <= 200) && (y >= 190) && (y <= 240)) && (cou2 == 0)) { tft.fillRect(120,190,80,50,WHITE); cou2 = cou2 + 1; } if(((x >= 0) && (x <= 50) && (y >= 80) && (y <= 160)) && (cou3 == 0)) { tft.fillRect(0,80,50,80,WHITE); cou3 = cou3 + 1; } if(((x >= 270) && (x <= 320) && (y >= 80) && (y <= 160)) && (cou4 == 0)) { tft.fillRect(270,80,50,80,WHITE); cou4 = cou4 + 1; } if(((x >= 70) && (x <= 120) && (y >= 60) && (y <= 110)) && (cou5 == 0)) { tft.fillRect(70,60,50,50,WHITE); cou5 = cou5 + 1; } if(((x >= 200) && (x <= 250) && (y >= 60) && (y <= 110)) && (cou6 == 0)) { tft.fillRect(200,60,50,50,WHITE); cou6 = cou6 + 1; } if(((x >= 70) && (x <= 120) && (y >= 130) && (y <= 180)) && (cou7 == 0)) { tft.fillRect(70,130,50,50,WHITE); cou7 = cou7 + 1; } if(((x >= 200) && (x <= 250) && (y >= 130) && (y <= 180)) && (cou8 == 0)) { tft.fillRect(200,130,50,50,WHITE); cou8 = cou8 + 1; } if((cou1 >= 1) && (cou2 >= 1) && (cou3 >= 1) && (cou4 >= 1) && (cou5 == 0) && (cou6 == 0) && (cou7 == 0) && (cou8 == 0))//青をよけて赤だけ消した { tft.fillScreen(WHITE); tft.setTextSize(3); tft.setCursor(60,100); tft.print("Time="); tft.print((millis() - tim) / 1000); tft.println("sec"); tft.setCursor(60,130); tft.print(((60000 - (millis() - tim)) / 1000) + 80);//20点ボーナスが加算される tft.print("point"); flg = 10; while(flg == 10)//動的バランス計測が終わったのでループさせる { TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z > 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } if((cou1 >= 1) && (cou2 >= 1) && (cou3 >= 1) && (cou4 >= 1) && (cou5 >= 1) && (cou6 >= 1) && (cou7 >= 1) && (cou8 >= 1)) { tft.fillScreen(WHITE); tft.setTextSize(3); tft.setCursor(60,100); tft.print("Time="); tft.print((millis() - tim) / 1000); tft.println("sec"); tft.setCursor(60,130); tft.print(((60000 - (millis() - tim)) / 1000) + 60); tft.print("point"); flg = 10; while(flg == 10)//動的バランス計測が終わったのでループさせる { TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z > 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } if((millis() - tim) >= 60000)//制限時間60秒が過ぎた { flg = 0; tft.fillScreen(WHITE); tft.setTextSize(3); tft.setCursor(5,105); tft.print("Time Over "); if(cou1 >= 1) { flg = flg + 10; } if(cou2 >= 1) { flg = flg + 10; } if(cou3 >= 1) { flg = flg + 10; } if(cou4 >= 1) { flg = flg + 10; } if(cou5 >= 1) { flg = flg + 5; } if(cou6 >= 1) { flg = flg + 5; } if(cou7 >= 1) { flg = flg + 5; } if(cou8 >= 1) { flg = flg + 5; } tft.print(flg); tft.print("point"); flg = 10; while(flg == 10)//動的バランス計測が終わったのでループさせる { TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z > 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } } } } } if(((p.x > 200) && (p.x < 280)) && ((p.z > 300) && (p.z < MAXPRESSURE)))//歩行分析モード { flg = 4; tft.fillScreen(WHITE); tft.setTextSize(3); tft.setCursor(65,105); tft.print("Step 15sec"); gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; while((gram1 < 4) && (gram2 < 4) && (gram3 < 4) && (gram4 < 4))//ボードに人が乗っていないときはループさせて待つ { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; } ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; tft.fillScreen(WHITE); int vx[999]; int vy[999]; int vz[999]; long vx1000 = 0;//x座標の平均計算用 long vy1000 = 0; long vz1000 = 0; while((gram1 > 4) || (gram2 > 4) || (gram3 > 4) || (gram4 > 4))//センサーの値がどれか1つでも4kgを超えていれば人が乗っていると判断 { if(cou9 == 0) { delay(2000);//人がボードに乗ってから2秒待つ cou9 = 1; } if((xx == 0) && (yy == 0))//最初の1回だけ実行される { suu = 0;//データ出力の回数 xx = 1; if((abs(gram1 - ogram1)) > 15) //15kg以上一気に重さが変わっていればノイズだと判断する { gram1 = ogram1; } if((abs(gram2 - ogram2)) > 15) { gram2 = ogram2; } if((abs(gram3 - ogram3)) > 15) { gram3 = ogram3; } if((abs(gram4 - ogram4)) > 15) { gram4 = ogram4; } ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; //4つのセンサーの値から重心座標を求める int x = int((gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4))); int y = int((gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4))); int z = int(gram1 + gram2 + gram3 + gram4); tim = millis(); vx[0] = x; vy[0] = y; vz[0] = z; if(z < 1) { z = 1; } tft.fillCircle(x,y,4,BLACK); ax = x; ay = y; az = z; } else { gram1 = Scale1.get_units(1) * 6666; gram2 = Scale2.get_units(1) * 7777; gram3 = Scale3.get_units(1) * 8888; gram4 = Scale4.get_units(1) * 9999; /*if((abs(gram1 - ogram1)) > 30) //30kg以上一気に重さが変わっていればノイズだと判断する { gram1 = ogram1; } if((abs(gram2 - ogram2)) > 30) { gram2 = ogram2; } if((abs(gram3 - ogram3)) > 30) { gram3 = ogram3; } if((abs(gram4 - ogram4)) > 30) { gram4 = ogram4; }*/ ogram1 = gram1; ogram2 = gram2; ogram3 = gram3; ogram4 = gram4; //4つのセンサーの値から重心座標を求める int x = int((gram1 + gram2) * (320 / (gram1 + gram2 + gram3 + gram4))); int y = int((gram1 + gram4) * (240 / (gram1 + gram2 + gram3 + gram4))); int z = int(gram1 + gram2 + gram3 + gram4); suu = suu + 1; vx[suu] = x; vy[suu] = y; vz[suu] = z; tft.fillCircle(ax,ay,4,WHITE);//1つ前の黒丸を消す tft.fillCircle(x,y,4,BLACK); ax = x; ay = y; az = z; if(((millis() - tim) >= 15000) || (suu == 1000)) { Maxx = vx[suu]; Minx = vx[suu]; Maxz = vz[suu]; while(suu >= 1) { suu = suu - 1; if(Maxx < vx[suu]) { Maxx = vx[suu]; } if(Minx > vx[suu]) { Minx = vx[suu]; } if(Maxz < vz[suu]) { Maxz = vz[suu]; } } int sw1 = (32000 / (Maxx - Minx));//整数型で少しでも精度が上がるよう100倍・10倍する int sw2 = (2400 / Maxz); tft.fillScreen(WHITE); suu = 0; vx1000 = 0;//vx1000にはx座標の合計・平均が入る vy1000 = 0; vz1000 = 0; while(suu <= 999) { tft.fillRect((((vx[suu] - Minx) * sw1) / 100),(240 - ((vz[suu] * sw2) / 10)),1,((vz[suu] * sw2) / 10),BLACK); delay(10); /*Serial.print(vx[suu]); Serial.print(" "); Serial.print(vy[suu]); Serial.print(" "); Serial.println(vz[suu]);*/ vx1000 = vx1000 + vx[suu]; vy1000 = vy1000 + vy[suu]; vz1000 = vz1000 + vz[suu]; suu = suu + 1; } vx1000 = vx1000 / 10;//平均を求めるので1000で割るべきだが精度を上げるため10で割る vy1000 = vy1000 / 10; vz1000 = vz1000 / 10; //現時点でvx等には平均値*100が入っている suu = 0; double vx1001 = 0;//vx1001には標準偏差が入る double vy1001 = 0; double vz1001 = 0; while(suu <= 999) { vx1001 = vx1001 + pow(((vx[suu] * 100) - vx1000) , 2); vy1001 = vy1001 + pow(((vy[suu] * 100) - vy1000) , 2); vz1001 = vz1001 + pow(((vz[suu] * 100) - vz1000) , 2); suu = suu + 1; } vx1001 = (sqrt(vx1001 / 1000)) / 100; vy1001 = (sqrt(vy1001 / 1000)) / 100; vz1001 = (sqrt(vz1001 / 1000)) / 100; tft.fillRect(158,0,4,240,RED); delay(5000); tft.fillScreen(WHITE); tft.setTextSize(2); tft.setCursor(5,5); tft.print("Ave x="); tft.print((((vx1000 / 100) - 160) / 4444),1);//座標値をcmに変換 tft.print(" y="); tft.print((((vy1000 / 100) - 160) / 5555),1); tft.print(" z="); tft.println((vz1000 / 100),1); tft.setCursor(5,25); tft.print("Std x="); tft.print((vx1001 / 4444),1);//座標値をcmに変換 tft.print(" y="); tft.print((vy1001 / 5555),1); tft.print(" z="); tft.print(vz1001,1); flg = 10; while(flg == 10)//歩行評価が終わったのでループさせる { TSPoint p = ts.getPoint(); if(((p.x > 0) && (p.x < 190)) && ((p.y > 835) && (p.y < 895)) && ((p.z > 300) && (p.z > 480)))//隠し機能 パネルの左下を押すとリセット { asm volatile (" jmp 0"); } pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); } } } } } } }