|
| 1 | +/* |
| 2 | + Reading distance from the laser based VL53L1X |
| 3 | + By: Nathan Seidle |
| 4 | + SparkFun Electronics |
| 5 | + Date: April 4th, 2018 |
| 6 | + License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). |
| 7 | +
|
| 8 | + SparkFun labored with love to create this code. Feel like supporting open source hardware? |
| 9 | + Buy a board from SparkFun! https://www.sparkfun.com/products/14667 |
| 10 | +
|
| 11 | + Reading distance and outputting the distance and speed to a SerLCD. |
| 12 | + This is based on the Speed Trap project: https://www.youtube.com/watch?v=uC9CkhJiIaQ |
| 13 | +
|
| 14 | + Are you getting weird readings? Make sure the vacuum tape has been removed. |
| 15 | +
|
| 16 | +*/ |
| 17 | +#include <Wire.h> |
| 18 | + |
| 19 | +#include "SparkFun_VL53L1X_Arduino_Library.h" |
| 20 | +VL53L1X distanceSensor; |
| 21 | + |
| 22 | +#include <SoftwareSerial.h> |
| 23 | + |
| 24 | +SoftwareSerial lcd(10, A3); // RX, TX |
| 25 | + |
| 26 | +//Store distance readings to get rolling average |
| 27 | +#define HISTORY_SIZE 8 |
| 28 | +int history[HISTORY_SIZE]; |
| 29 | +byte historySpot; |
| 30 | + |
| 31 | +long lastReading = 0; |
| 32 | +long lastDistance = 0; |
| 33 | +float newDistance; |
| 34 | +int maxDistance = 0; |
| 35 | + |
| 36 | +const byte numberOfDeltas = 8; |
| 37 | +float deltas[numberOfDeltas]; |
| 38 | +byte deltaSpot = 0; //Keeps track of where we are within the deltas array |
| 39 | + |
| 40 | +//This controls how quickly the display updates |
| 41 | +//Too quickly and it gets twitchy. Too slow and it doesn't seem like it's responding. |
| 42 | +#define LOOPTIME 50 |
| 43 | + |
| 44 | +int maxMPH = 0; //Keeps track of what the latest fastest speed is |
| 45 | +long maxMPH_timeout = 0; //Forget the max speed after some length of time |
| 46 | + |
| 47 | +#define maxMPH_remember 3000 //After this number of ms the system will forget the max speed |
| 48 | + |
| 49 | +boolean readingValid = false; |
| 50 | +long validCount = 0; |
| 51 | + |
| 52 | +void setup(void) |
| 53 | +{ |
| 54 | + Wire.begin(); |
| 55 | + Wire.setClock(400000); |
| 56 | + |
| 57 | + Serial.begin(115200); |
| 58 | + Serial.println("VL53L1X Qwiic Test"); |
| 59 | + |
| 60 | + lcd.begin(9600); |
| 61 | + |
| 62 | + lcd.write(254); //Move cursor to beginning of first line |
| 63 | + lcd.write(128); |
| 64 | + lcd.print("Distance: 3426 "); |
| 65 | + lcd.print("12 mph "); |
| 66 | + |
| 67 | + if (distanceSensor.begin() == false) |
| 68 | + { |
| 69 | + Serial.println("Sensor offline!"); |
| 70 | + } |
| 71 | + |
| 72 | + for (int x = 0 ; x < HISTORY_SIZE ; x++) |
| 73 | + history[x] = 0; |
| 74 | +} |
| 75 | + |
| 76 | +void loop(void) |
| 77 | +{ |
| 78 | + |
| 79 | + //Write configuration block of 135 bytes to setup a measurement |
| 80 | + distanceSensor.startMeasurement(); |
| 81 | + |
| 82 | + //Poll for completion of measurement. Takes 40-50ms. |
| 83 | + while (distanceSensor.newDataReady() == false) |
| 84 | + delay(5); |
| 85 | + |
| 86 | + int distanceMM = distanceSensor.getDistance(); |
| 87 | + |
| 88 | + lastReading = millis(); |
| 89 | + |
| 90 | + history[historySpot] = distanceMM; |
| 91 | + if (historySpot++ == HISTORY_SIZE) historySpot = 0; |
| 92 | + |
| 93 | + long avgDistance = 0; |
| 94 | + for (int x = 0 ; x < HISTORY_SIZE ; x++) |
| 95 | + avgDistance += history[x]; |
| 96 | + |
| 97 | + avgDistance /= HISTORY_SIZE; |
| 98 | + |
| 99 | + |
| 100 | + //Every loop let's get a reading |
| 101 | + newDistance = distanceMM / 10; //Go get distance in cm |
| 102 | + |
| 103 | + int deltaDistance = lastDistance - newDistance; |
| 104 | + lastDistance = newDistance; |
| 105 | + |
| 106 | + //Scan delta array to see if this new delta is sane or not |
| 107 | + boolean safeDelta = true; |
| 108 | + for (int x = 0 ; x < numberOfDeltas ; x++) |
| 109 | + { |
| 110 | + //We don't want to register jumps greater than 30cm in 50ms |
| 111 | + //But if we're less than 1000cm then maybe |
| 112 | + //30 works well |
| 113 | + if ( abs(deltaDistance - deltas[x]) > 40) safeDelta = false; |
| 114 | + } |
| 115 | + |
| 116 | + //Insert this new delta into the array |
| 117 | + if (safeDelta) |
| 118 | + { |
| 119 | + deltas[deltaSpot++] = deltaDistance; |
| 120 | + if (deltaSpot > numberOfDeltas) deltaSpot = 0; //Wrap this variable |
| 121 | + } |
| 122 | + |
| 123 | + //Get average of the current deltas array |
| 124 | + float avgDeltas = 0.0; |
| 125 | + for (byte x = 0 ; x < numberOfDeltas ; x++) |
| 126 | + avgDeltas += (float)deltas[x]; |
| 127 | + avgDeltas /= numberOfDeltas; |
| 128 | + |
| 129 | + //22.36936 comes from a big coversion from cm per 50ms to mile per hour |
| 130 | + float instantMPH = 22.36936 * (float)avgDeltas / (float)LOOPTIME; |
| 131 | + |
| 132 | + instantMPH = abs(instantMPH); //We want to measure as you walk away |
| 133 | + |
| 134 | + ceil(instantMPH); //Round up to the next number. This is helpful if we're not displaying decimals. |
| 135 | + |
| 136 | + if (instantMPH > maxMPH) |
| 137 | + { |
| 138 | + maxMPH = instantMPH; |
| 139 | + maxMPH_timeout = millis(); |
| 140 | + } |
| 141 | + |
| 142 | + if (millis() - maxMPH_timeout > maxMPH_remember) |
| 143 | + { |
| 144 | + maxMPH = 0; |
| 145 | + } |
| 146 | + |
| 147 | + int signalRate = distanceSensor.getSignalRate(); |
| 148 | + if (signalRate < 10) |
| 149 | + { |
| 150 | + readingValid = false; |
| 151 | + validCount = 0; |
| 152 | + } |
| 153 | + else |
| 154 | + { |
| 155 | + validCount++; |
| 156 | + if (avgDistance > maxDistance) maxDistance = avgDistance; |
| 157 | + } |
| 158 | + |
| 159 | + if (validCount > 10) readingValid = true; |
| 160 | + |
| 161 | + if (readingValid == false) |
| 162 | + { |
| 163 | + instantMPH = 0; |
| 164 | + avgDistance = 0; |
| 165 | + } |
| 166 | + |
| 167 | + //Convert mm per millisecond to miles per hour |
| 168 | + //float mph = distanceDelta * 2.236936 / (float)timeDelta; |
| 169 | + //mph *= -1; //Flip sign as we will be traveling towards sensor, decreasing the distance |
| 170 | + |
| 171 | + lcd.write(254); //Move cursor |
| 172 | + lcd.write(138); |
| 173 | + lcd.print(" "); |
| 174 | + lcd.write(254); //Move cursor |
| 175 | + lcd.write(138); |
| 176 | + |
| 177 | + if (readingValid == true) |
| 178 | + lcd.print(avgDistance); |
| 179 | + else |
| 180 | + lcd.print(maxDistance); |
| 181 | + |
| 182 | + lcd.write(254); //Move cursor |
| 183 | + lcd.write(192); |
| 184 | + lcd.print(instantMPH, 0); |
| 185 | + lcd.print(" mph "); |
| 186 | + |
| 187 | + delay(25); |
| 188 | +} |
| 189 | + |
0 commit comments