Problem with sound in project bubble generator

Hello.

my name is Alan and i'm a new Arduino user.

I started to make the Gigantic Bubble Generator

It is working fine but the only thing I can not get working is the sirene.

I hope maybe one of you can have a look at the code and see what is wrong.

This is the link to the project

The code is:

/**
 *
 * BubbleBot Control Code
 *
 * By: Zvika Markfeld, Jonatan Bien, Uri Kareev
 *
 **/
#include <Servo.h> 
#include <Wire.h> 
#include "MCP23017.h"

#define upperBoundrySwitchPin 2
#define lowerBoundrySwitchPin 13
#define servoPin 3
#define fanPin 4
#define sirenPin 12
#define speakerPin 9

#define l298Ena 8
#define l298In1 7
#define l298In2 6

#define CTRL_JOY_UP 2
#define CTRL_JOY_RIGHT 4
#define CTRL_JOY_LEFT 8
#define CTRL_JOY_DOWN 16
#define CTRL_BUTTON1 32 // lower
#define CTRL_BUTTON2 64 // higher
#define CTRL_SWITCH 1

#define ROLLER_FORWARD 1
#define ROLLER_BACKWARD 2
#define ROLLER_IDLE 3
#define ROLLER_STOP 4


// 1:debug 2:info 3:warning 4:fatal
#define LOG_LEVEL 2

const int NUM_OF_SPREADS = 2;
const int SPREAD_SPEED = 30;
const int UNSPREAD_SPEED = 20;
const int SPREAD_DURATION = 2000;
const int SPREAD_DURATION_DECREASE_FACTOR = 3;
const int FAN_TURN_OFF_DELAY = 2000;
const int CHECK_LOWER_BOUNDARY_DELAY = 2000;


// Servo boundry values
const int arm_open_pos = 9;
const int arm_closed_pos = 60;

Servo myservo;
MCP23017 portExpander;
int rollerState;
int armPosition;

int sirenFreq = 100;
int sirenFreqStep;
int sirenMode;
int sirenFreqDir = 1;

void setup() { 
  Serial.begin(115200);
  log(">> Initializing");
  pinMode(lowerBoundrySwitchPin, INPUT);
  pinMode(upperBoundrySwitchPin, INPUT);
  pinMode(sirenPin, OUTPUT);
  pinMode(l298Ena, OUTPUT);
  pinMode(l298In1, OUTPUT);
  pinMode(l298In2, OUTPUT);
  pinMode(fanPin, OUTPUT);

  digitalWrite(lowerBoundrySwitchPin, HIGH); // pullup
  log(">> Bootstrapping I2C(1)");
  Wire.begin();
  log(">> Bootstrapping I2C(2)");
  portExpander.SetDir(1,0);  // all input
  log(">> Bootstrapping I2C(3)");
  portExpander.WriteByte(1, 255); // pullup
  
  log(">> Attaching Arm Servo");
  myservo.attach(servoPin);
  setArm(arm_closed_pos);
  log(">> Resetting machine state");
  resetState();
}

void loop() { 
  if(isInManual()) {
    digitalWrite(sirenPin, HIGH);
    handleManual();
  }
  else {
    digitalWrite(sirenPin, LOW);
    handleAuto();
  }
}


void handleManual() {
  log("ALERT: entering MANUAL CONTROL");
  while(isInManual()) {
    sirenMode = 0;
    // handle fan
    if(isFanButtonPressed()) {
      sirenMode = 1;
      setFan(true);
    }
    else {
      setFan(false);
    }

    // UP-DOWN
    if(isJoyUp()) {
      sirenMode = 2;
      handleJoyUp();
    }
    else if(isJoyDown()) {
      sirenMode = 2;
      handleJoyDown();
    }
    else {
      idle();
    }

    // LEFT_RIGHT
    if(isJoyRight()) {
      sirenMode = 3;
      if(armPosition > arm_open_pos) {
        setArm(armPosition - 1);
      }
      else {
        setArm(arm_open_pos);
      }
      delayWithSirenUpdate(SPREAD_SPEED);
    }
    else if(isJoyLeft()) {
      sirenMode = 3;
      if(armPosition < arm_closed_pos) {
        setArm(armPosition + 1);
      }
      else {
        setArm(arm_closed_pos);
      }
      delayWithSirenUpdate(SPREAD_SPEED);
    }
    //>>>
    //handleSiren();
  }
  log("exiting MANUAL CONTROL");
  noTone(speakerPin);
}

void handleSiren() {
  switch(sirenMode) {
    case 0:
      sirenFreqStep = 7;
      break;
    case 1:
      sirenFreqStep = 75;
      break;
    case 2:
      sirenFreqStep = 50;
      break;
    case 3:
      sirenFreqStep = 50;
      break;
  }
  tone(speakerPin, sirenFreq);
  sirenFreq+= (sirenFreqStep * sirenFreqDir);
  if(sirenFreq >= 2000 || sirenFreq <= 50) {
    sirenFreqDir *= -1;
  }
}

void delayWithSirenUpdate(int duration) {
  long start = millis();
  while(millis() - start < duration) {
    //>>>
    // handleSiren();
    delay(10);
  }
}

void handleJoyUp() {
  log("detected JOY_UP", 1);
  if(atUpperBoundary()) {
    log("upper boundry reached, setting engine to idle", 1);
    idle();
  }
  else if (rollerState != ROLLER_FORWARD) {
    log("setting engine to forward", 1);
    forward();
  }
}

void setFan(boolean b) {
    digitalWrite(fanPin, b ? HIGH : LOW);
}

void handleJoyDown() {
  log("detected JOY_DOWN", 1);
  if(atLowerBoundary()) {
    log("upper boundry reached, setting engine to idle", 1);
    idle();
  }
  else if (rollerState != ROLLER_BACKWARD) {
    log("setting engine to backward", 1);
    backward();
  }
}

void forward() {
  digitalWrite(l298Ena, HIGH);
  digitalWrite(l298In1, LOW);
  digitalWrite(l298In2, HIGH);
  rollerState = ROLLER_FORWARD;
}

void backward() {
  digitalWrite(l298Ena, HIGH);
  digitalWrite(l298In1, HIGH);
  digitalWrite(l298In2, LOW);
  rollerState = ROLLER_BACKWARD;
}

void idle() {
  digitalWrite(l298In1, LOW);
  digitalWrite(l298In2, LOW);
  digitalWrite(l298Ena, LOW);
  rollerState = ROLLER_IDLE;
}

void stop() {
  digitalWrite(l298In1, LOW);
  digitalWrite(l298In2, LOW);
  digitalWrite(l298Ena, LOW);
  rollerState = ROLLER_STOP;
}

void setArm(int val) {
  myservo.write(val);
  armPosition = val;
}

void handleAuto() { 
  while(isInAuto()) {
    forward();
    log("waiting for upper boundry");
    while(!atUpperBoundary()) {
      if(isInManual()) {
        return;
      }
    }
    log("upper boundry detected");
    idle();
  
    log("switching fan on");
    digitalWrite(fanPin, HIGH);
  
    int pos;
    int times;
    for(times = 0; times < NUM_OF_SPREADS; ++times) {
      // spread arms
      for(pos = arm_closed_pos; pos>=arm_open_pos; pos-=1) {  
        if(isInManual()) {
          return;
        }
        setArm(pos);
        delay(SPREAD_SPEED);
      }
      int currDelay = SPREAD_DURATION * (SPREAD_DURATION_DECREASE_FACTOR - times) / SPREAD_DURATION_DECREASE_FACTOR;
      log("waiting: ");
      log(currDelay);
      delay(currDelay);
      // close arms
      for(pos = arm_open_pos; pos <arm_closed_pos; pos += 1)  {
        if(isInManual()) {
          return;
        }
        setArm(pos);
        delay(UNSPREAD_SPEED);
      }
    }
  
  
    // start bringing arms down
    log("taking arms down");
    backward();

    delay(FAN_TURN_OFF_DELAY);
    log("switching fan off");
    digitalWrite(fanPin, LOW);
    
    log("waiting for lower boundry");
    // not needed, as FAN_TURN_OFF_DELAY is used
    // delay(CHECK_LOWER_BOUNDARY_DELAY);
    while (!atLowerBoundary() && !atUpperBoundary()) {
      if(isInManual()) {
        return;
      }
    }
    idle();
    if(atUpperBoundary()) {
      log("ERROR: failed recognizing lower boundary, reached upper boundary. check lower boundary switch and restart", 3);
      while(true);
    }
    else {
      log("lower boundry detected");
    }
  }
} 

void resetState() {
  log("Resetting state");
  setArm(arm_closed_pos);
  forward();
  
  log("waiting for upper boundry");
  waitForUpperBoundary();
  log("upper boundry detected, going down");
  backward();
  
  delay(CHECK_LOWER_BOUNDARY_DELAY);
  log("waiting for lower boundry");
  waitForLowerBoundary();
  idle();
  log("Machine state was reset");
}


/**
 * buttons are pulled up, method will hopefully help preventing stupid programming errors due to the inverse logic
 **/
boolean buttonEnabled(int value, int mask) {
  return !(value & mask);
}

boolean isInManual() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_SWITCH);
}

boolean isInAuto() {
  return !isInManual();
}

boolean isFanButtonPressed() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_BUTTON1);
}

boolean isJoyUp() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_JOY_UP);
}

boolean isJoyDown() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_JOY_DOWN);
}

boolean isJoyLeft() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_JOY_LEFT);
}

boolean isJoyRight() {
  int buttonState = portExpander.ReadByte(1);
  return buttonEnabled(buttonState, CTRL_JOY_RIGHT);
}


void log(String msg) {
  log(msg, 2);
}

void log(String msg, int level) {
  if(level >= LOG_LEVEL) {
    Serial.println(msg); 
  }
}

boolean atLowerBoundary() {
 return (digitalRead(lowerBoundrySwitchPin) == LOW); 
}

boolean atUpperBoundary() {
 return (digitalRead(upperBoundrySwitchPin) == HIGH); 
}

void waitForUpperBoundary() {
  log("waiting for upper boundary");
  while(!atUpperBoundary());
}

void waitForLowerBoundary() {
  log("waiting for lower boundary");
  while(!atLowerBoundary() && !atUpperBoundary());
  if(atUpperBoundary()) {
    log("ERROR: failed recognizing lower boundary, reached upper boundary. check lower boundary switch and restart", 3);
    idle();
    while(true);
  }
  
  
}

regards Alan

The two calls to handleSiren() are commented out so you will not get any speaker output on Pin 9. I guess the author found the siren more annoying than helpful.

Hi, thanks for your reply.

The sirene should only work when switch to manual.
What means you activate the joystick.
At the moment you move the arms or activate the fan thaen the sound should be going.

regards Alan

What do you have connected to pins 9 (speaker) and 12 (siren)?

What do you have connected to pins 9 (speaker) and 12 (siren)?

A little speaker and a piezo.
At the moment I activate the joystick the piezo gives an irritating beep.
But the beep not stop and the sound should change with pressing fan button or move arms with joystick.

It's going to run the piezo buzzer as long as the Control switch is in the Manual position.

It's going to run the piezo buzzer as long as the Control switch is in the Manual position.

Yes it is. If that is what it should be I don't know.
But what i want is the siren sounds.
I still got it not working