8x1 LED bar

I'm trying to make a led bar that indicates the distance between two objects. I'm using a HC SR04 ultrasonic sensor and 74hc595 shift register for the 8 leds.

The ultrasonic sensor is tested and it works(it stores the distance to an integer). And the 74hc595 is working with the shiftout tutorial examples.
The problem is 7 of 8 leds are on and when I move the objects closer than 5cm the last lights up. In the serial monitor I only get distances less then 5 cm(5 cm is max dont know why)
this is my code I'm a beginner so it might be a stupid mistake :smiley:

#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     13  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 4;
////Pin connected to DS of 74HC595
int dataPin = 7;
byte broj = B00000000;
void setup() {
    Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

}

void loop() {
  delay(50);
  int cm = sonar.ping_cm(); // Send out the ping, get the results in centimeters.
  Serial.print("Udaljenost: ");
  Serial.print(cm);         // Print the result (0 = outside the set distance range, no ping echo)
  Serial.println("cm");
  
  //LEDS
if (cm <=3 && cm>1){
broj = B11111111;}
else if(cm>100 || cm==0){
broj = B00000000;}
else if(75<cm && cm<=100){
broj = B00000001;}
else if(50<cm && cm<=75){
broj = B00000011;}
else if(30<cm && cm<=50){
broj = B00000111;}
else if (15<cm && cm<=30){
broj = B00001111;}
else if(10<cm && cm<=15){
broj = B00011111;}
else if(5<cm && cm<=10){
broj = B00111111;}
else if(3<cm && cm<=5){
broj = B01111111;}
  
  shiftOut(dataPin, clockPin, MSBFIRST, broj);
  digitalWrite(latchPin, HIGH);
  delay(100);
  digitalWrite(latchPin, LOW);
  

}

Probably, you also should "wrap" else's in curly brackets :

else 
{if(30<cm && cm<=50){
broj = B00000111;}
}

So, I would look for math formula to "linearize" a data set, than use a "map" function on 0 - 7. Or , may be linearize ad scale same time.

Is this

The ultrasonic sensor is tested and it works(it stores the distance to an integer).

consistent with this? How can the sensor work if it only goes to 5?

In the serial monitor I only get distances less then 5 cm(5 cm is max dont know why)

The code looks OK to me, but the condition you end up with also happens to be the last else if. Suspicious. As a sanity check, change the last else if to another value, for instance

else if (15<cm && cm<=30){
broj = B00001111;}

and see if the result changes. If it does, then you must listen to Magician and use more curly braces.

I tried to put brackets after every else but i get an error : 'else' without a previous 'if' and changing the last else if to another values changes nothing.

I know that the sensor works by using the newping example it goes up to 200cm and its really accurate. [quote author=Magician

link=topic=117125.msg881577#msg881577 date=1344030782]
Probably, you also should "wrap" else's in curly brackets :

else 
{if(30<cm && cm<=50){
broj = B00000111;}
}

So, I would look for math formula to "linearize" a data set, than use a "map" function on 0 - 7. Or , may be linearize ad scale same time.
[/quote]
Could you point me to an example or something similar because I'm a beginner.
Thank you.

This code generate no errors at compilation time:

  //LEDS
if (cm <=3 && cm>1){
broj = B11111111;}
else { if(cm>100 || cm==0){
broj = B00000000;}
else { if(75<cm && cm<=100){
broj = B00000001;}
else { if(50<cm && cm<=75){
broj = B00000011;}
else { if(30<cm && cm<=50){
broj = B00000111;}
else { if (15<cm && cm<=30){
broj = B00001111;}
else { if(10<cm && cm<=15){
broj = B00011111;}
else { if(5<cm && cm<=10){
broj = B00111111;}
else { if(3<cm && cm<=5){
broj = B01111111;}
}}}}}}}}

As your approximation looks close to square root for me, better way would be: cm = sqrt ( cm * 0.5 ); May be you could try with different coefficient (0.5), "squeezing" cm to 0-7 range you can use barGraph example in arduino IDE.