Sending and receiving multiplexed values from an ultrasonic sensor.

Hello,

I want to connect 4 multiplexed HC-SR04 sensors, and
display this onto an LCD screen.
On the Arduino Due.
I use this code:

//connect  HC-SR04 5v to Arduino 5v and GND to Arduino GND
/*shift register pin connections
Pin 1-7 and Pin 15 - outputs, HC-SR04 "trig" pins
Pin 8 and 13 to GND
Pin 10 and 16 to 5v
Pin 11, 12, 14 see below
Pin 9 - not used
*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

long duration, inches, cm;
int indec, cmdec;
int inchconv = 147; // ratio between puls width and inches
int cmconv = 59; // ratio between pulse width and cm

int distCm[] = {0, 0, 0, 0, 0, 0, 0, 0};
const int numSens =  1; //number of sensors used
const int clockPin = 8;//IC pin 11
const int latchPin = 9;//IC pin 12
const int dataPin = 7;//IC pin 14
const int echo = 6; //connect "Echo" pin from all Sensors to this pin

byte leds = 0;

void setup()
{
 lcd.begin(16, 2);
 Serial.begin(9600);
 pinMode(latchPin, OUTPUT);
 pinMode(echo, INPUT);
 pinMode(dataPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
}//end setup

void loop() {
 digitalWrite(dataPin, LOW);
 delayMicroseconds(2);
 digitalWrite(dataPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(dataPin, LOW);

 // read the length of the return pulse on Echo output
 duration = pulseIn(echo, HIGH);

 scan();
 int i;
 for (i = 0; i < numSens; i++) {
   lcd.setCursor (0, 0);
   lcd.print(i + 1);
   lcd.print("-");
   lcd.print(distCm[i]);
   lcd.print("cm\t");

 }//end for
 lcd.print("\n");
 delay(500);
}
//end loop

void scan() {
 leds = 0;
 int i;
 int timePulse;
 //call function "updateShiftRegister" to cycle through all sensors
 updateShiftRegister();
 //cycles 4 times for the 4 sensors -can extend up to 8 for one shift register
 for (i = 0; i < numSens; i++) {
   bitSet(leds, i);
   updateShiftRegister();
   delayMicroseconds(10);
   bitClear(leds, i);
   updateShiftRegister();
   //connect sensor "trigger" pins to IC pin 7,6,5,4 = array num 0,1,2,3 - can extend up to 8
   // The speed of sound is 340 m/s or 29 microseconds per centimeter.
   // The ping travels out and back, so to find the distance of the
   // object we take half of the distance travelled.
   distCm[i] = ((pulseIn(echo, HIGH, 25000)) / 2) / 29;
 }//end for
}//end scan

void updateShiftRegister()
{
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, LSBFIRST, leds);
 digitalWrite(latchPin, HIGH);
}//end shift

It only shows one value at the screen, but how do I get all the values from all
the sensors onto the screen ?

Thank you in advance !

It's a shame that your code has been mangled by the forum software because of your use of an array index of i being interpreted as a command to turn on italics. If you had read and followed the advice in the 2 posts by Nick Gammon at the top of the forum page you would have known about code tags. Please edit your post, select the code and click on the </> icon on the far left above the editor window and save the edited post.

I can't get your code to compile.

lcd.print("-");
lcd.print(distCm);  //   distCm is not a null terminated array so will not print like this.  Use a for loop.
lcd.print("cm\t");
// object we take half of the distance travelled.
 distCm = ((pulseIn(echo, HIGH, 25000)) / 2) / 29;      // missing array indexer SB distCm[i]
 }//end for

Fixing those two errors allow it to compile. Don't know if it will work, though.

Note the use of code tags?

UKHeliBob:
It's a shame that your code has been mangled by the forum software because of your use of an array index of i being interpreted as a command to turn on italics. If you had read and followed the advice in the 2 posts by Nick Gammon at the top of the forum page you would have known about code tags. Please edit your post, select the code and click on the </> icon on the far left above the editor window and save the edited post.

I have modified my post. It now has a code tag.

I have made a picture of the whole lay-out.
On the serial monitor it worked fine, but now on
the LCD screen it won't show all the values measured
by the hc-sr04 sensors.

I am completely new to this, but got it working until
we had to show the values on the LCD screen.

That diagram is not accurate. I immediately see two problems.
#1 - There are no connections to the transistors driving the 'Trig' pins.
#2 - Do you have the two left-hand side pins of the transistors shorted together? And what are those transistors, by the way? (Part number)

I haven't looked further at your connections for errors. Go over it carefully. It's no good to us if it's not accurate.

Edit: Oh, I see. The black wires aren't all ground. That might have been a good idea. Very misleading.
You still need to sort out what you've done with those transistors though. You need to remove the shorts, then consider pullup resistors. Still need to know what type they are, too.

Generally, when drawing up a circuit like this, it's a good idea to reserve red for +V, black for GND, then other colours for signal.

It's a school project, so I will send more details as soon as possible.

It only shows one value at the screen, but how do I get all the values from all
the sensors onto the screen ?

How many sensors do you have?

const int numSens =  1; //number of sensors used

Looks to me like you are getting all 1 of the values...

I know you can change that. I now use 4 sensors, and got it working
on the serial monitor, but now I want to display everything onto an
LCD screen. I can only get 1 value onto the LCD screen, so that's
my problem. Does somebody now how to get all the sensor values
onto the LCD screen ?

Can you post you current working code?
Also, what size is your LCD screen? 16x2, 20x4 or something else?

I use a 16x2 LCD display.
This is the code I am using now:

//connect  HC-SR04 5v to Arduino 5v and GND to Arduino GND
/*shift register pin connections
Pin 1-7 and Pin 15 - outputs, HC-SR04 "trig" pins
Pin 8 and 13 to GND
Pin 10 and 16 to 5v
Pin 11, 12, 14 see below
Pin 9 - not used
*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

long duration, inches, cm;
int indec, cmdec;
int inchconv = 147; // ratio between puls width and inches
int cmconv = 59; // ratio between pulse width and cm

int distCm[] = {0, 0, 0, 0, 0, 0, 0, 0};
const int numSens =  4; //number of sensors used
const int clockPin = 8;//IC pin 11
const int latchPin = 9;//IC pin 12
const int dataPin = 7;//IC pin 14
const int echo = 6; //connect "Echo" pin from all Sensors to this pin

byte leds = 0;

void setup()
{
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}//end setup

void loop() {
  digitalWrite(dataPin, LOW);
  delayMicroseconds(2);
  digitalWrite(dataPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(dataPin, LOW);

  // read the length of the return pulse on Echo output
  duration = pulseIn(echo, HIGH);

  scan();
  int i;
  for (i = 0; i < numSens; i++) {
    lcd.setCursor (0, 0);
    lcd.print(i + 1);
    lcd.print("-");
    lcd.print(distCm[i]);
    lcd.print("cm\t");

  }//end for
  lcd.print("\n");
  delay(500);
}
//end loop

void scan() {
  leds = 0;
  int i;
  int timePulse;
  //call function "updateShiftRegister" to cycle through all sensors
  updateShiftRegister();
  //cycles 4 times for the 4 sensors -can extend up to 8 for one shift register
  for (i = 0; i < numSens; i++) {
    bitSet(leds, i);
    updateShiftRegister();
    delayMicroseconds(10);
    bitClear(leds, i);
    updateShiftRegister();
    //connect sensor "trigger" pins to IC pin 7,6,5,4 = array num 0,1,2,3 - can extend up to 8
    // The speed of sound is 340 m/s or 29 microseconds per centimeter.
    // The ping travels out and back, so to find the distance of the
    // object we take half of the distance travelled.
    distCm[i] = ((pulseIn(echo, HIGH, 25000)) / 2) / 29;
  }//end for
}//end scan

void updateShiftRegister()
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
}//end shift
  for (i = 0; i < numSens; i++) {
    lcd.setCursor (0, 0);
    lcd.print(i + 1);
    lcd.print("-");
    lcd.print(distCm[i]);
    lcd.print("cm\t");

  }//end for

Why are you setting the cursor back to 0, 0 each time before printing each value ? The only value you will see is the last one because previous values will be overwritten.

I have tried multiple things the last couple of days. The only problem seems to be the code. Can somebody have a look at the code, how to separate all the values. And print all of them under each other onto the screen. It would be a great help. :slight_smile:

//connect  HC-SR04 5v to Arduino 5v and GND to Arduino GND
/*shift register pin connections
Pin 1-7 and Pin 15 - outputs, HC-SR04 "trig" pins
Pin 8 and 13 to GND
Pin 10 and 16 to 5v
Pin 11, 12, 14 see below 
Pin 9 - not used
*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

long duration, inches, cm;
int indec, cmdec;
int inchconv = 147; // ratio between puls width and inches
int cmconv = 59; // ratio between pulse width and cm

int distCm[]={0,0,0,0,0,0,0,0};
const int numSens=1;//number of sensors used
const int clockPin = 8;//IC pin 11
const int latchPin = 9;//IC pin 12
const int dataPin = 7;//IC pin 14
const int echo=6;//connect "Echo" pin from all Sensors to this pin

byte leds = 0;

void setup() 
{
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}//end setup

void loop(){
    digitalWrite(dataPin, LOW);
  delayMicroseconds(2);
  digitalWrite(dataPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(dataPin, LOW);
  
   // read the length of the return pulse on Echo output
  duration = pulseIn(echo, HIGH);

  scan();
  int i;
  for(i=0;i<numSens;i++){
    lcd.setCursor (0,0);
    lcd.print(i+1);
    lcd.print("-");    
    lcd.print(distCm[i]);
    lcd.print("cm\t");
 
  }//end for
      lcd.print("\n");
  delay(500);}
//end loop

void scan(){
  leds=0;
  int i;
  int timePulse;
  //call function "updateShiftRegister" to cycle through all sensors 
  updateShiftRegister();
  //cycles 4 times for the 4 sensors -can extend up to 8 for one shift register
  for(i=0;i<numSens;i++){ 
          bitSet(leds, i);
       updateShiftRegister();
      delayMicroseconds(10);
          bitClear(leds,i);
       updateShiftRegister();
//connect sensor "trigger" pins to IC pin 7,6,5,4 = array num 0,1,2,3 - can extend up to 8 
     distCm[i]=((pulseIn(echo,HIGH,25000))/2)/29.1;
  }//end for
}//end scan

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}//end shift
  int i;
  for(i=0;i<numSens;i++){
    lcd.setCursor (0,0);
    lcd.print(i+1);
    lcd.print("-");    
    lcd.print(distCm[i]);
    lcd.print("cm\t");
 
  }//end for

To start with don't keep putting the cursor back to 0, 0. Do that once before the for loop. Inside the for loop use the value of i to position the cursor. If it is 0 then print at 0, 0. If it is 1 print at say 8, 0 and so on.

UKHeliBob:

  int i;

for(i=0;i<numSens;i++){
    lcd.setCursor (0,0);
    lcd.print(i+1);
    lcd.print("-");   
    lcd.print(distCm[i]);
    lcd.print("cm\t");

}//end for


To start with don't keep putting the cursor back to 0, 0. Do that once before the for loop. Inside the for loop use the value of i to position the cursor. If it is 0 then print at 0, 0. If it is 1 print at say 8, 0 and so on.

Okay I,ve put the 0,0 before the "for loop" have i done this correctly. What do you mean with: use the value of i to position the cursor. If it is 0 then print at 0, 0. If it is 1 print at say 8, 0 and so on ?
maybe you could show it as a code. :wink:

scan();
  lcd.setCursor (0, 0);
  int i;
  for (i = 0; i < numSens; i++) {
    lcd.print(i + 1);
    lcd.print("-");
    lcd.print(distCm[i]);
    lcd.print("cm\t");

maybe you could show it as a code.

No. You are the one that insists on explicitly positioning the cursor. YOU need to figure out what the arguments to the setCursor() function are. Stop guessing at coding.

Once you KNOW what the first argument means, and what the second argument means, you will know exactly where printing is going to happen. So, you can print the ith value at the ith position.

What do you mean with: use the value of i to position the cursor. If it is 0 then print at 0, 0. If it is 1 print at say 8, 0 and so on ?

There are cleverer ways to do it but do it the clumsy way first. Inside the for loop test the value of i then use setCursor() to position the cursor to the position for the value to be printed. 4 tests and 4 setCursor()s (actually only 3 because for i == 0 the cursor will already be at 0, 0)

I am assuming that you know what setCursor() does. If not then some reading is required.