If statement only works with a completely unrelated function in front of it

Hey everybody, I'm so very confused at what's happening with my code.

Just some backgorund: this project is using an Arduino Mega 2560, ultrasonic sensors, vibration motors, transistors, and an LED strip in order to detect distance from an object and properly alert.

Everything works, the step I'm working on now is activating the vibration motor and LEDs when the sensors detect a distance below 25 cm as an example. (This can be seen in the loop function towards the end of it)

However, the if statement in the loop function to toggle the vibration motor ONLY does the "else" portion, unless I put the makeLEDs() function before it.

For example, dist1 = 22 cm, therefore the if statement should print "Starting vibration". However, unless the makeLEDs() function is on the line before, it does not work.

The goal is to put the makeLEDs() function inside the if statement.

Once I remove the makeLEDs() function the if statement does not work anymore.

Things I've tried:

  1. Using a brand new distance function, however this current one still works the best (found online).
  2. Replacing the makeLEDs() function before the if statement with delay(40)

At this point I'm really confused.

See code below: I can answer any and all questions regarding the code as I really need some help. It's been three days haha.

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <FastLED.h>

// Defining where each pin is connected for ultrasonic sensors
const int triggerPin = 2;
const int echoPin = 3;
const int triggerPin2 = 4;
const int echoPin2 = 5;
const int triggerPin3 = 6;
const int echoPin3 = 7;
const int triggerPin4 = 8;
const int echoPin4 = 9;
const int triggerPin5 = 10;
const int echoPin5 = 11;

// Defining transistor pins to toggle vibrations
const int transPin1 = 13;

// OLED Declaration screen size in pixels
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Defining the LED strip parameters
#define LED_PIN     12
#define NUM_LEDS    60
CRGB leds[NUM_LEDS];

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(9600);           // For outputting distance data
  pinMode(echoPin,INPUT_PULLUP);  // Someone said this also helped with errant readings...
  pinMode(triggerPin, OUTPUT);  // Make the triggerPin an OUTPUT
  pinMode(echoPin2,INPUT_PULLUP);  // Someone said this also helped with errant readings...
  pinMode(triggerPin2, OUTPUT);  // Make the triggerPin an OUTPUT
  pinMode(echoPin3,INPUT_PULLUP);  // Someone said this also helped with errant readings...
  pinMode(triggerPin3, OUTPUT);  // Make the triggerPin an OUTPUT
  pinMode(echoPin4,INPUT_PULLUP);  // Someone said this also helped with errant readings...
  pinMode(triggerPin4, OUTPUT);  // Make the triggerPin an OUTPUT
  pinMode(echoPin5,INPUT_PULLUP);  // Someone said this also helped with errant readings...
  pinMode(triggerPin5, OUTPUT);  // Make the triggerPin an OUTPUT
  digitalWrite(triggerPin, LOW);
  digitalWrite(triggerPin2, LOW);
  digitalWrite(triggerPin3, LOW);
  digitalWrite(triggerPin4, LOW);
  digitalWrite(triggerPin5, LOW);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS); // Sets up the LED strip
  FastLED.setBrightness(10 );
  display.display();
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.display();
}

void loop()
{
  int dist1 = 0;
  int dist2 = 0;
  int dist3 = 0;
  dist1 = getDistance(triggerPin, echoPin);
  dist2 = getDistance(triggerPin2, echoPin2);
  dist3 = getDistance(triggerPin3, echoPin3);
  printToSerial(1, dist1);
  printToSerial(2, dist2);
  printToSerial(3, dist3);
  printToDisplay(1, dist1);
  printToDisplay(2, dist2);
  printToDisplay(3, dist3);
  display.display();
  display.clearDisplay();
  display.setCursor(0,0);
  makeLEDs();
  
  if (dist1 < 25) 
  {
    Serial.print("Starting vibration\n");
    startVibrate();
  }
  
  else
  {
    Serial.print("Stopping vibration\n");
    stopVibrate();
  }
}

void printToSerial(int index, int distance)
{
  char format[16];
  sprintf(format, "Distance %i: %i \n", index, distance);
  Serial.print(format);
}

void printToDisplay(int index, int distance)
{
  char format[16];
  sprintf(format, "Distance %i: %i cm", index, distance);
  display.println(format);
}

int getDistance(int trigger, int echo) 
{

  long duration = 0;
  int distance = 0;
  int watchloop = 0;

  // Clear the triggerPin by setting it LOW and wait for any pulses to expire:

  digitalWrite(trigger, LOW);      // setting state to low and
  delay(2);                           // waiting 2,000uS (or 686cm (>22ft) to eliminate "echo noise")

  // only grab values under 20ft/610cm (for some reason, 676 is a common return error for ∞ distance)

  while ( (distance == 0) || (distance > 610) ) {

    // Trigger the sensor by setting the triggerPin high for 10 microseconds:

    digitalWrite(trigger, HIGH);         // start sending the 40kHz wave...
    delayMicroseconds(20);                  // sending for 20uS
    digitalWrite(trigger, LOW);          // stop sending 40kHz wave

    // Read the echoPin. pulseIn() duration of when the wave-echo stops (in microseconds):

    duration = pulseIn(echo, HIGH);

    // Calculate the distance:

    distance = duration * 0.034 / 2;

    // Catch funky ∞ distance readings

    watchloop++;        
    if (watchloop > 20){      // If errant "676" readings 20 times
      distance = 610;         // set distance to 610cm (20ft) 
      break;                  // and break out of loop (not really needed if forced to 610)
    }
  }

  return (distance);
}

void makeLEDs()
{
  for (int i = 0; i <= 20; i++) {
    leds[i] = CRGB ( 255, 255, 255);
    FastLED.show();

  }
  delay(20);
  for (int i = 20; i >= 0; i--) {
    leds[i] = CRGB ( 255, 0, 0);
    FastLED.show();

  }
  delay(20);
}

void startVibrate()
{
  digitalWrite(transPin1, HIGH);
}

void stopVibrate()
{
  digitalWrite(transPin1, LOW);
}

You are probably overflowing your buffer, messing with the stack and other variables when you do this

 char format[16];
  sprintf(format, "Distance %i: %i \n", index, distance);

After that all bets are off

I can't see where there would be an obvious proble; HOWEVER, you do have a memory corruption problem in the following functions:

void printToSerial(int index, int distance)
{
  char format[16];
  sprintf(format, "Distance %i: %i \n", index, distance);
  Serial.print(format);
}

void printToDisplay(int index, int distance)
{
  char format[16];
  sprintf(format, "Distance %i: %i cm", index, distance);
  display.println(format);
}

If you count out the number of characters possible for the format string string you can easily end up with more than 16. If you write past the end of the array you could easily corrupt other values, including any that are on the stack (possibly dista1).

When you move the makeLEDs() call you rearrange dynamic memory which may cause it to work.

Fix this first and see what happens.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.