Help please

Hi there, whilst i have had an arduino for a while i am still new to programming and hardware is more my thing (yet i love to learn)
With that in mind, i started on a project that uses a TIP122 to operate a relay to bypass a switch depending on the proximity to an object using the input from an ultrasonic sensor.

The hardware is all sorted yet the code is causing me some issues, so i have tried to go back to a basic code (turning on the on board LED, depending on the proximity to an object.

can anyone offer a solution, to what i am sure is simple. yet has eluded me

thanks for your time and sorry if the answer is starring me in the face :slight_smile:

/* Ping))) Sensor
 
 The circuit:
 	* +V connection of the PING))) attached to +5V
 	* GND connection of the PING))) attached to ground
 	* SIG connection of the PING))) attached to digital pin 7
 * SIG connection of the TIP circuit attached to Pin 8
 
 
 */

// this constant won't change.  It's the pin number
// of the sensor's output:
#include <NewPing.h>

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
int tip122Light = 13; // TIP122 lightstrip curcuit connected to pin 
int val = 0;

int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimu range needed
long duration, distance; //Duration used to calculate distance

int warningZone1 = 10; // range in cm which is considered to be dangerous first cycle of the striplight
int warningZone2 = 7; // range in cm which is considered to be dangerous second cycle of the striplight 
int warningZone3 = 5; // range in cm which is considered to be dangerous third cycle of the striplight

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(tip122Light, OUTPUT);
}

void loop()
{
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  distance = duration/58.2;

  // convert the time into a distance


  Serial.println(distance); // placed to see if the senor is reading correctly
{
 val = digitalRead(echoPin);
}
  if(distance <= warningZone1);
  { 
    digitalWrite(tip122Light, val); // if the distance from the sensor to the obstacal is equal to or less than the distance advised in warninZOne 1 then turn the light on
  
   } 
}

(deleted)

if(distance <= warningZone1);
Get rid of the ; at the end of this line.

I've used similar code for a range finder and I'm not sure what you're trying to achieve with:

val = digitalRead(echoPin)

Why not just cut that line out and have this instead:

 if(distance <= warningZone1);
  { 
    digitalWrite(tip122Light, HIGH); // if the distance from the sensor to the obstacal is equal to or less than the distance advised in warninZOne 1 then turn the light on
  
   } 
else
  {
    digitalWrite(tip122Light, LOW);
  }
{

Snowman815901:
I've used similar code for a range finder and I'm not sure what you're trying to achieve with:

val = digitalRead(echoPin)

Why not just cut that line out and have this instead:

 if(distance <= warningZone1);

{
   digitalWrite(tip122Light, HIGH); // if the distance from the sensor to the obstacal is equal to or less than the distance advised in warninZOne 1 then turn the light on
 
  }
else
 {
   digitalWrite(tip122Light, LOW);
 }
{

You've still got that problematic semicolon.

Hi all, thanks for your input.

i have done some homework and have used the switch case coding to assist me, what i am trying to do is eventually mimic/bypass a physical switch using a TIP122 transistor and a relay.

to do this i want "press" the button (digitalWrite HIGH and LOW with a delay) alternatively depending on the proximity to an object.

i only want this to happen once each time it is in the "zone", currently it is running continuously each time it is in the "zone".

i have been looking at "do While" statements, but am unsure of their placement to achieve the desired result, any ideas?

please see below my new code.

/*
 HC-SR04 Ping distance sensor:
 VCC to arduino 5v 
 GND to arduino GND
 Echo to Arduino pin 7 
 Trig to Arduino pin 8
 
 This sketch originates from Virtualmix: http://goo.gl/kJ8Gl
 Has been modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html
 And modified further by ScottC here: http://arduinobasics.blogspot.com/
 on 10 Nov 2012.
 */


#define echoPin 8 // Echo Pin
#define trigPin 9 // Trigger Pin
#define LEDPin 13 // Onboard LED

int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop() {
  /* The following trigPin/echoPin cycle is used to determine the
   distance of the nearest object by bouncing soundwaves off of it. */
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); 
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  distance = duration/58.2;

  if (distance >= maximumRange || distance <= minimumRange){
    /* Send a negative number to computer and Turn LED ON 
     to indicate "out of range" */
    Serial.println("out of range");
  }
  else {
    /* Send the distance to the computer using Serial protocol, and
     turn LED OFF to indicate successful reading. */
    Serial.println(distance);
  }
  {
    switch (distance) {
    case 25:
      digitalWrite(LEDPin, LOW);
      break;
    case 20:
    case 19:
    case 18:
    case 17:
    case 16:
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      break;
    case 15:
    case 14:
    case 13:
    case 12:
    case 11:
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      delay (100);
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      break;
    case 10:
    case 9:
    case 8:
    case 7:
    case 6:
    case 5:
    case 4:
    case 3:
    case 2:
    case 1:
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      delay (100);
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      delay (100);
      digitalWrite(LEDPin, HIGH);
      delay (100);
      digitalWrite(LEDPin, LOW);
      break;
    }
  }
  //Delay 50ms before next reading.
  delay(50);
}

In my projects, when I need something to happen only when a given state changes, I set up 2 variables, an "old" variable that equals the state before a reading and a "new" variable that equals the state after the reading. When the "old" does not equal (!=) the "new", do thing X.

I've added a few lines to the code you just posted:

/*
 HC-SR04 Ping distance sensor:
 VCC to arduino 5v 
 GND to arduino GND
 Echo to Arduino pin 7 
 Trig to Arduino pin 8
 
 This sketch originates from Virtualmix: http://goo.gl/kJ8Gl
 Has been modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html
 And modified further by ScottC here: http://arduinobasics.blogspot.com/
 on 10 Nov 2012.
 */


#define echoPin 8 // Echo Pin
#define trigPin 9 // Trigger Pin
#define LEDPin 13 // Onboard LED

int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

////////////////////////////////////////////// Added These //////////////////////////////////////////////
int zoneFlag;
int oldZoneFlag;
int newZoneFlag;
//////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop() {
  /* The following trigPin/echoPin cycle is used to determine the
   distance of the nearest object by bouncing soundwaves off of it. */
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); 
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  distance = duration/58.2;



  oldZoneFlag = zoneFlag;  // <-------------------------------------------- "OLD" state.
  if (distance >= maximumRange || distance <= minimumRange){
    /* Send a negative number to computer and Turn LED ON 
     to indicate "out of range" */
    Serial.println("out of range");
    zoneFlag = 0; // <----------------------------------------------------- State is set to 0 if out of range.
  }
  else {
    /* Send the distance to the computer using Serial protocol, and
     turn LED OFF to indicate successful reading. */
    Serial.println(distance);
    zoneFlag = 1; // <----------------------------------------------------- State is set to 1 if in range.
  }
  newZoneFlag = zoneFlag;  // <------------------------------------------  "NEW" state.



  
  {
    if (oldZoneFlag == 0 && newZoneFlag == 1) // <----------------------- If the state used to be 0 but now is 1 do the blink thing. Otherwise, do nothing.
    {
      switch (distance) {
      case 25:
        digitalWrite(LEDPin, LOW);
        break;
      case 20:
      case 19:
      case 18:
      case 17:
      case 16:
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        break;
      case 15:
      case 14:
      case 13:
      case 12:
      case 11:
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        delay (100);
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        break;
      case 10:
      case 9:
      case 8:
      case 7:
      case 6:
      case 5:
      case 4:
      case 3:
      case 2:
      case 1:
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        delay (100);
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        delay (100);
        digitalWrite(LEDPin, HIGH);
        delay (100);
        digitalWrite(LEDPin, LOW);
        break;
      }
    }
  }
  //Delay 50ms before next reading.
  delay(50);
}

This should achieve what you're going for.

Also, If you're planning on filling in every one of those switch cases, I suspect that you could do it a lot easier with some old fashioned arithmetic and a "for" loop.

For example:

if (oldZoneFlag == 0 && newZoneFlag == 1)
    {
      int blinks = (1/distance)* 25; // Replace 25 with the max possible value of distance;
      for (int i = 0; i< blinks; i++)
      {
        digitalWrite(LEDpin, HIGH);
        delay(50);
        digitalWrite(LEDpin, LOW);
        delay(50);       
      }
      // for example:
      // if distance = 25, blinks will = 1. The LED will blink 1 time.
      // if distance = 10, blinks will = 2.5 The arduino will truncate this to 2 as it's an int. The LED will blink 2 times.
      // if distance = 5, blinks will = 5. The LED will blink 5 times.
      // if distance = 1, blinks will = 25. The LED will blink 25 times.
  }
  //Delay 50ms before next reading.
  delay(50);
}

Obviously, I don't know exactly what you want the LED to do, so you'd have to adjust accordingly. This is just an example. I'm pretty sure you don't want the LED to blink 200 times.

The use of switch cases would make more sense though if the response to the distance value wasn't linear.

Also also, if you need the program to do anything else while blinking the LEDs, you'll need to get rid of the delays and use a timer based setup instead.

mgodsell1973:
i only want this to happen once each time it is in the "zone", currently it is running continuously each time it is in the "zone".

What you're looking for is called edge detection and is demonstrated in the StateChangeDetection example.