Merging two codes, reading from ultrasonic sensor to display

Hi,

I have been working on ultrasonic distance meter with display and got the distance out of the sensor with this code

#include "URMSerial.h"

#define DISTANCE 1
#define TEMPERATURE 2
#define ERROR 3
#define NOTREADY 4

int ledPin = 13;
URMSerial urm;

void setup() {

  Serial.begin(9600); // Sets the baud rate to 9600
  urm.begin(2,3,9600); // RX Pin, TX Pin, Baud Rate pinMode(ledPin, OUTPUT);
}

void loop() 
{ 
  // Request a distance reading from the URM37
  urm.requestMeasurement(DISTANCE); // You may call this as many times as you like. It will only send once

  // Avoid fetching the distance until we're sure the reading is ready
  if(urm.hasReading()) 
  {
    int value; // This value will be populated
    switch(urm.getMeasurement(value)) // Find out the type of request
    {
    case DISTANCE: // Double check the reading we recieve is of DISTANCE type
      Serial.println(value, DEC); // Fetch the distance in centimeters from the URM37

      delay(200);
      break;
    }
  }
}

I would like to merge it to this, but since I am not compleatly sure what parts of the code are nessessary it’s quite dificult. If you show me what parts are nessasary I would like to try merge them myself.

// Arduino pins connected to the 4511
const int LedA = 5;
const int LedB = 8;
const int LedC = 7;
const int LedD = 6;

// Arduino pins connected to the segment driver transistors
const int Led1 = 4;
const int Led2 = 3;
const int Led3 = 2;

long count = 0;
int output = 0;
int remain = 0;

void setup()
{
  // Let the Arduino know which pins go where
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  digitalWrite(Led1, HIGH);
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);
}

void loop()
{
  // The counter runs from 0-9999 so divide this by 10 as
  // we only have three display segments
  output = count / 10;

  // Display the first digit
  // The order of these steps is important to prevent
  // visible 'bleeding' on the display
  Display(output / 100); // Send first digit to the 4511
  output = output % 100; // Calculate next digit
  digitalWrite(Led1, LOW); // Illuminate first segment
  delay(2); // Wait
  digitalWrite(Led1, HIGH); // Extinguish first segment

  // Display the second digit
  Display(output / 10);
  output = output % 10;
  digitalWrite(Led2, LOW);
  delay(2);
  digitalWrite(Led2, HIGH);

  // Display the third digit
  Display(output);
  digitalWrite(Led3, LOW);
  delay(2);
  digitalWrite(Led3, HIGH);

  // Count to 9999 then reset
  count = count + 1;
  if (count > 9999)
  {
    count = 0;
  }
}

// Function to display the digit 'n'
void Display(int n)
{
  if ( n > 9 )
  {
    n = 9;
  }

  if ( n < 0 )
  {
    n = 0;
  }

  if ( n / 8 == 1 )
  {
    digitalWrite(LedD, HIGH);
  }
  else
  {
    digitalWrite(LedD, LOW);
  }

  n = n % 8;

  if ( n / 4 == 1 )
  {
    digitalWrite(LedC, HIGH);
  }
  else
  {
    digitalWrite(LedC, LOW);
  }
  n = n % 4;

  if ( n / 2 == 1 )
  {
    digitalWrite(LedB, HIGH);
  }
  else
  {
    digitalWrite(LedB, LOW);
  }
  n = n % 2;

  if ( n == 1 )
  {
    digitalWrite(LedA, HIGH);
  }
  else
  {
    digitalWrite(LedA, LOW);
  }

}

Replace this Serial.println(value, DEC); with the display part of the second sketch - lose the "count". You realise that this doesn't drive the seven-segment digits directly, but uses an external BCD decoder?

This:

// Function to display the digit 'n'
void Display(int n)

is just perverse!

I do realise that and think it should be taken into the account some how in the code.

Dose this look anything like you thought? :grin:

#include "URMSerial.h"

#define DISTANCE 1
#define TEMPERATURE 2
#define ERROR 3
#define NOTREADY 4

int ledPin = 13;
URMSerial urm;
int output = 0;

// Arduino pins connected to the 4511
const int LedA = 5;
const int LedB = 8;
const int LedC = 7;
const int LedD = 6;

// Arduino pins connected to the segment driver transistors
const int Led1 = 4;
const int Led2 = 3;
const int Led3 = 2;

void setup() {

  Serial.begin(9600); // Sets the baud rate to 9600
  urm.begin(9,10,9600); // RX Pin, TX Pin, Baud Rate pinMode(ledPin, OUTPUT);

  // Let the Arduino know which pins go where
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  digitalWrite(Led1, HIGH);
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);
}

void loop() 
{ 
  // Request a distance reading from the URM37
  urm.requestMeasurement(DISTANCE); // You may call this as many times as you like. It will only send once

  // Avoid fetching the distance until we're sure the reading is ready
  if(urm.hasReading()) 
  {
    int value; // This value will be populated
    switch(urm.getMeasurement(value)) // Find out the type of request
    {
    case DISTANCE: // Double check the reading we recieve is of DISTANCE type



      digitalWrite(Led1, LOW); // Illuminate first segment
      delay(2); // Wait
      digitalWrite(Led1, HIGH); // Extinguish first segment

      // Display the second digit
      Display(output / 10);
      output = output % 10;
      digitalWrite(Led2, LOW);
      delay(2);
      digitalWrite(Led2, HIGH);

      // Display the third digit
      Display(output);
      digitalWrite(Led3, LOW);
      delay(2);
      digitalWrite(Led3, HIGH);

      delay(200);
      break;
    }
  }
}

Well, something like that, but without TEMPERATURE, ERROR, NOTREADY defined (they're never used)

You may want to put "value" into "output", and you'll still need a version of "Display", which you're now missing.

I am sorry but I can't figure out how to do that. :blush:

Here's what I manage to cobble together.

#include "URMSerial.h"
#define DISTANCE 1

int ledPin = 13;
URMSerial urm;
int output = 0;

// Arduino pins connected to the 4511
const int LedA = 5;
const int LedB = 8;
const int LedC = 7;
const int LedD = 6;

// Arduino pins connected to the segment driver transistors
const int Led1 = 4;
const int Led2 = 3;
const int Led3 = 2;

void setup() {

  Serial.begin(9600); // Sets the baud rate to 9600
  urm.begin(9,10,9600); // RX Pin, TX Pin, Baud Rate pinMode(ledPin, OUTPUT);

  // Let the Arduino know which pins go where
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  digitalWrite(Led1, HIGH);
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);
}

void loop() 
{ 
  // Request a distance reading from the URM37
  urm.requestMeasurement(DISTANCE); // You may call this as many times as you like. It will only send once

  // Avoid fetching the distance until we're sure the reading is ready
  if(urm.hasReading()) 
  {
    int value; // This value will be populated
    switch(urm.getMeasurement(value)) // Find out the type of request
    {
    case DISTANCE: // Double check the reading we recieve is of DISTANCE type



      // Display the first digit
      Display(value / 100);       // Send first digit to the 4511
      output = value % 100;      // Calculate next digit
      digitalWrite(Led1, LOW);    // Illuminate first segment
      delay(2);                   // Wait
      digitalWrite(Led1, HIGH);   // Extinguish first segment

      // Display the second digit
      Display(value /10);
      output = value % 10;
      digitalWrite(Led2, LOW);
      delay(2);
      digitalWrite(Led2, HIGH);

      // Display the third digit
      Display(value);
      output = value;
      digitalWrite(Led3, LOW);
      delay(2);
      digitalWrite(Led3, HIGH);

      delay(200);
      break;
    }
  }
}

I am sorry but I can’t figure out how to do that.

You mean that you can not figure out how to assign the value of one variable to another?

If that's what it means, yes. As I'm new to coding, I need some basic help.

I don't even understand how these two lines works and is it the left or right first digit.

Display(value / 100);       // Send first digit to the 4511
output = value % 100;      // Calculate next digit
Display(value / 100);       // Send first digit to the 4511
output = value % 100;      // Calculate next digit

Imagine "value" has the value "123". Dividing it (integer division) by 100 gives the value 1. The modulo operator % returns the remainder of the integer division, in this case 23.

Thanks for the clarification.

AWOL: This:

// Function to display the digit 'n'
void Display(int n)

is just perverse!

Do you mean the code after it is useless or some how wrong? Because that's the only thing I can think of what I should add to the code.

Do you mean the code after it is useless or some how wrong?

No, it clearly isn't wrong, but if I were planning to do what it does, I can't think of a better way of making it less efficient or more obscure.

But thats what I’m missing right now?

I have no way of knowing what you're missing at the moment. Me, I'm missing my nice warm bed.

Hi,

I have now tested the code and it works, but it needs some tweaks. When the distance increases the displays starts to flicker. I believe it’s because it takes longer time to get the distance by the sensor. How can I make the display code to be primary code and the measurement code to be secondary so it is not done with same frequency?

#include "URMSerial.h"
#define DISTANCE 1

int ledPin = 13;
URMSerial urm;

// Arduino pins connected to the 4511
const int LedA = 4;
const int LedB = 5;
const int LedC = 6;
const int LedD = 7;

// Arduino pins connected to the segment driver transistors
const int D1 = 8;
const int D2 = 9;
const int D3 = 10;

void setup() {

  Serial.begin(9600); // Sets the baud rate to 9600
  urm.begin(2,3,9600); // RX Pin, TX Pin, Baud Rate pinMode(ledPin, OUTPUT);

  // Let the Arduino know which pins go where
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);
  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
}

void loop() 
{ 
  // Request a distance reading from the URM37
  urm.requestMeasurement(DISTANCE);

  // Avoid fetching the distance until we're sure the reading is ready
  if(urm.hasReading()) 
  {
    int value; // This value will be populated
    switch(urm.getMeasurement(value)) // Find out the type of request
    {
    case DISTANCE: // Double check the reading we recieve is of DISTANCE type
      Serial.println(value);


      // Display the first digit
      Display(value / 100);       // Send first digit to the 4511
      value = value % 100;      // Calculate next digit
      digitalWrite(D1, HIGH);    // Illuminate first segment
      delay(2);                  // Wait
      digitalWrite(D1, LOW);     // Extinguish first segment

      // Display the second digit
      Display(value / 10);
      value = value % 10;
      digitalWrite(D2, HIGH);
      delay(2);
      digitalWrite(D2, LOW);

      // Display the third digit

      Display(value);
      digitalWrite(D3, HIGH);
      delay(2);
      digitalWrite(D3, LOW);

      break;
    }
  }
} 

void Display(int n)
{
  if ( n > 9 )
  {
    n = 9;
  }

  if ( n < 0 )
  {
    n = 0;
  }

  if ( n / 8 == 1 )
  {
    digitalWrite(LedD, HIGH);
  }
  else
  {
    digitalWrite(LedD, LOW);
  }

  n = n % 8;

  if ( n / 4 == 1 )
  {
    digitalWrite(LedC, HIGH);
  }
  else
  {
    digitalWrite(LedC, LOW);
  }
  n = n % 4;

  if ( n / 2 == 1 )
  {
    digitalWrite(LedB, HIGH);
  }
  else
  {
    digitalWrite(LedB, LOW);
  }
  n = n % 2;

  if ( n == 1 )
  {
    digitalWrite(LedA, HIGH);
  }
  else
  {
    digitalWrite(LedA, LOW);
  }
}

How can I make the display code to be primary code and the measurement code to be secondary so it is not done with same frequency?

Move where value is defined, to the beginning of loop. Make value a static variable. Have urm.GetMeasurement() value it. Display() the value on every pass through loop, regardless of whether urm.hasReading() is true or not.