====== Távolságmérés SHARP optikai szenzorral ====== Az SHARP optikai szenzorok leírása [[hu:arduino:distant#sharp_ir_taverzekelok|itt található]]. A legnagyobb távmérést igérő GP2Y0A60SZ(LF) vettem meg az Ebay-ről egy további projektemhez tesztelésre, és rögtön az alábbi problémákba sikerült ezzel belefutnom. A táblázatba beírtam a megoldásaimat is: ^Probléma a szenzorral^Megoldás (amit használtam)| |A távolságmérés elvileg 150 cm maximumot ígér, a mérésem szerint ez 110 cm fölött igencsak bizonytalan|Ez van, a mérés maximumát 110 cm-ben határoztam meg| |A szenzor karakterisztikáján látszik, hogy adott távolság alatt (ebben az esetben ez kb 10 cm) "csal", azaz rossz értékeket mér|A szenzort úgy kell telepíteni, hogy ebben a tartományban (..10cm) ne legyen lehetősége mérni (mert egyébként hülyeséget fog jelezni)| |A szenzormérés bizonytalan, néha nagyon kiugró méréseket tud adni (ezt a soros monitorral lehet kiszúrni|Egy kicsit bonyolultabb (szórás- és) átlagszámítási eljárással ez kiszűrhető| A projekthez felhasználtam még egy 4 pozíciós 7 szegmensű kijelzőt is, hogy lássam, mennyire stabil a mérés. Ez értelemszerűen elhagyható, leírása [[hu:arduino:seven_segments#szegmenses_kijelzo_tm1637_ic-vel|itt található]]. A mért értékek közötti szűrőeljárás paraméterezhető. ===== Vezetékezés ===== **GP2Y0A60SZ(LF) sensor:** \\ SEN: Arduino A0 \\ **7 szegmensű kijelző**: \\ CLK: Arduino A4 \\ DIO: Arduino A5 \\ GND: Arduino GND \\ 5V: Arduino 5V \\ ===== Program ===== // Vamos Sandor 2018 - ob121.com // Distance measuring with GP2Y0A60SZ(LF) sensor // and display with TM1637 7-segment dispay #include "TM1637.h" // 7-segment Display driver #define CLK A4 // CLK pin for 7-segment Display #define DIO A5 // DIO pin for 7-segment Display TM1637 tm1637(CLK,DIO); // init Display #define avg_element 20 // the numbers of elemens from measuring to calc avg #define max_diff 10 // maximum tolerant for an element (from avg) in % unsigned long time_stamp, time_stamp_now; // timer int sensorPin = A0; // a0 GP2Y0A60SZ(LF) sensor int avg [avg_element]; // array for avg calc int average, max_val, Amax, Amin; // avg, max different, abs diff max-min int inside, Aval, Distance; // inside in tol, value, distance int disp_one, disp_ten, disp_hundred; // display 3 pos. int show = 0; // pointer int sensorValue = 0; // value from sensor void setup() { Serial.begin(9600); // opt: serial monitor tm1637.init(); // 7-segment dispay settings tm1637.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7; } void loop() { sensorValue = analogRead(sensorPin); // read sensor (with 50 ms gap) avg[show] = sensorValue; // fill a position in array show++; // next position (pointer) if (show > avg_element) {show = 0;}; // if fill the array, start from 0 pos. average = 0; // start value for (int i=0; i < (avg_element + 1); i++) { // cycle in array average = average + avg[i]; // add for average } average = average / avg_element; // count average from array (all elements) max_val = average * (max_diff / 100.0); // calc tolerant to average Amax = average + max_val; // abs. min from average Amin = average - max_val; // abs. max to average int j=0; // startval inside=0; // startval for (int i=0; i < (avg_element + 1); i++) { // all elements in array if ((avg[i] < Amax) & (avg[i] > Amin)) { // if this element is inside from tolerant j++; // calc numbers inside = inside + avg[i]; // cals value } } inside = inside / j; // with tolerant corrected value if (inside > 0) {Aval = inside;}; // if this calculated value is valid, then use it // the measuring from dist.sensor is not proportional // then i use some measuring points from the curve. // Next is the calculation (correction) from this curve. if (Aval < 115) {Distance = 110; } else if (Aval < 120) {Distance = 110 - (Aval - 115)*2;} else if (Aval < 140) {Distance = 100 - (Aval - 120) /2;} else if (Aval < 154) {Distance = 90 - (Aval - 140) /1.4;} else if (Aval < 178) {Distance = 80 - (Aval - 154) /2.4;} else if (Aval < 206) {Distance = 70 - (Aval - 178) /2.8;} else if (Aval < 252) {Distance = 60 - (Aval - 206) /4.6;} else if (Aval < 318) {Distance = 50 - (Aval - 252) /6.4;} else if (Aval < 425) {Distance = 40 - (Aval - 318) /10.7;} else if (Aval < 558) {Distance = 30 - (Aval - 425) /13.3;} time_stamp_now = millis(); // time now if (abs(time_stamp_now - time_stamp) > 500) { // if 500ms elapsed time_stamp = time_stamp_now; // set new "old" timestamp disp_hundred = Distance / 100; // 3.pos for 7-segment display disp_ten = Distance / 10 - disp_hundred * 10; // 2.pos for 7-segment display disp_one = Distance - (disp_hundred * 100) - (disp_ten * 10); // 1.pos for 7-segment display tm1637.display(0,0); // Display values tm1637.display(1,disp_hundred); tm1637.display(2,disp_ten); tm1637.display(3,disp_one); } delay(50); // Waiting for dist.sensor 50 ms } **[[hu:project:arduino|>> Vissza az Arduino projektek listájához]]**