Hi everyone,
I'm having a few issues using map in a sketch. It could well be my understanding of the way it works but I've used it before and got the exact result I was expecting.
The line I am having trouble with is (I'll post full sketch at the end of this post) is ...
int distMap = map(dist, 5, 125, 0, 24);
The variable "dist" is a distance returned from an ultrasonic sensor (SR04) and is working perfectly (and very accurately!). I am building a parking radar which takes the distance from the sensor and lights the appropriate number of lines on 3 8x8 matrix displays. The closer you get the less lines are displayed and when the final one goes out you stop. I have mapped the distance to the variable distMap from 0 - 24 so that I could easily read off how many lines on the displays I needed to light up.
I had set up if statements to evaluate the size of the distMap ...
distMap == 24 (turns on all display lines)
distMap < 24 && distMap > 16 (turns on top 2 displays and shows distMap-16 lines on last display)
distMap <= 16 && distMap > 8 (turns on top display, shows distMap-8 lines on second, and turns off last)
distMap <= 8 && dist > 5 (turns off bottom 2 displays and shows distMap lines on top display)
else (if dist is less than 5 flash all lights as an emergency stop)
When I first ran the sketch it displayed erroneous data on the display and I was getting the emergency stop signal even though I knew the sensor was about 150cm from a solid wall I was using to test. As I pushed it closer the displays then began to work correctly. I added a serial output so I could see what was going on and it showed that when dist was greater than 125 (and max value I had supplied) the map was generating figures above 24 (again the max value I had selected). The mapping still seemed to be working correctly, i.e. when I moved the sensor to 130cm I would get a reading of 25, 135cm / 26, etc, but my (maybe flawed) understanding of the way that map worked was that it also constrained the figure to the max selected.
I have obviously changed the first if statement from distMap == 24 to distMap >= 24 which now gives the intended functionality but I am still scratching my head as to why this didn't work as intended.
If someone could explain what I've done wrong, or where my understanding is lacking, I would most grateful. Also if you have any suggestions on how I could make the code more efficient that'd be great.
Many thanks!
TH
/*
Sketch to control 3 8x8 matrices in a bar graph
style using an SR04 split into functions
*/
const int dataPin = 6; // 595 pin 14
const int latchPin = 4; // 595 pin 12
const int clockPin = 2; // 595 pin 11
/*
On 595 connect pins 8 & 13 to GND and
pins 10 & 16 to 5v. Outputs are on pins
15 & 1-7. Flowthrough is out pin 9 which
connects to pin 14 (data) on the next 595
*/
const int trigPin = 8;
const int echoPin = 10;
byte dispValue[] = {0, 1, 3, 7, 15, 31, 63, 127, 255}; // byte array of values to be displayed
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
//Serial.begin(9600);
}
void loop() {
int distance = getDist();
updateBar(distance);
}
int getDist(){
int duration, distance;
digitalWrite(trigPin, HIGH); // sends pulse of ...
delayMicroseconds(1000); // 1000 microseconds ...
digitalWrite(trigPin, LOW); // and this ends the pulse
duration = pulseIn(echoPin, HIGH); // listens for return pulse - sr04 output pulse length = time between send and receive
distance = (duration/2) / 29.1; // converts time into distance
return distance;
}
void updateBar(int dist){
int distMap = map(dist, 5, 125, 0, 24); // sets the 0 distance to 10 cm as a safety margin
//Serial.print("Distance = ");
//Serial.print(dist);
//Serial.print(" DistMap = ");
//Serial.println(distMap);
if (distMap >= 24) { // lights all displays
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);// output to 595
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(50);// prevents flicker
}
else if (distMap < 24 && distMap > 16) { // lights top two displays, and shows distMap-16 lines on bottom
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[distMap-16]);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(50);// prevents flicker
}
else if (distMap <= 16 && distMap > 8) { // lights top display, shows distMap-8 lines on middle and turns off bottom
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, 0);
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[distMap-8]);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[8]);
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(50);// prevents flicker
}
else if (distMap <= 8 && dist >= 5) { // turns off bottom two displays and shows distMap lines on top
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
shiftOut(dataPin, clockPin, MSBFIRST, dispValue[distMap]);// output to 595
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(50);// prevents flicker
}
else { // distance less than 5 // flashes alternate lines as emergency stop signal
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, 85);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, 85);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, 85);// output to 595
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(100);
digitalWrite(latchPin, LOW);// arms shift reg
shiftOut(dataPin, clockPin, MSBFIRST, 170);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, 170);// output to 595
shiftOut(dataPin, clockPin, MSBFIRST, 170);// output to 595
digitalWrite(latchPin, HIGH);//tells 595 to output received data
delay(100);
}
}