Bugs in the code. But I am unable to debug! Help!!

So, I am doing a small test project on some automated doors involving 2 boards, one to transmit, the other to receive.

I'm running into issues with the board that's receiving. Certain lines of my codes are probably bugging it out, but I really need those lines to work so that I can get the end result.

So, here are the codes.

#include <VirtualWire.h>

#include <ServoTimer2.h>
// a buffer to store the incoming messages
byte message[VW_MAX_MESSAGE_LEN]; 
// the size of the message
byte messageLength = VW_MAX_MESSAGE_LEN;

//int ledPin = 5;
int ServoPin = 3;
ServoTimer2 servo1;
const int buzzer = 9;

int redPin = 7;
int greenPin = 5 ;
int bluePin = 6 ;

//int ServoPin = 3;
//ServoTimer2 servo1;

void setup()
{
  // Initialize the serial monitor
  Serial.begin(9600);
  Serial.println("Device is ready");
  
  // Initialize the IO and ISR
  vw_setup(2000); // Bits per sec
  vw_rx_start(); // Start the receiver

  // set led pin as an output 
  //pinMode(ledPin, OUTPUT);
  servo1.attach(ServoPin);
  pinMode(redPin, OUTPUT);
  //Serial.println ("Check 1");
  pinMode(greenPin, OUTPUT);
  //Serial.println ("Check 2");
  pinMode(bluePin, OUTPUT);
  //Serial.println ("Check 3");
  pinMode(buzzer, OUTPUT);
}

void setColor(int red, int green, int blue)
{
  digitalWrite(redPin, red);
  digitalWrite(greenPin, green);
  digitalWrite(bluePin, blue);  
}

void loop()
{
  //setColor(255, 0, 0);  // red
  //delay(1000);
  //setColor(0, 255, 0);  // green
  //delay(1000);
  //setColor(0, 0, 255);  // blue
  //delay(1000);
  /*setColor(255, 255, 0);  // yellow
  delay(1000);  
  setColor(80, 0, 80);  // purple
  delay(1000);
  setColor(0, 255, 255);  // aqua
  delay(1000); */
  
  if (vw_get_message(message, &messageLength)) 
  {
    Serial.print("Received: ");
    for (int i = 0; i < messageLength; i++)
    {
      Serial.write(message[i]);
      if(message[i]=='J')
      {
        //digitalWrite(ledPin,HIGH);
        digitalWrite(redPin, HIGH);
        Serial.write(",  RED LED ON");
        setColor(255, 0, 0);
        servo1.write(750);
        delay(1000);
      }

      if(message[i]=='K')
      {
        //digitalWrite(ledPin,LOW);
        digitalWrite(greenPin,HIGH);
        Serial.write(", GREEN LED ON");
        setColor(0, 255,0 );
        servo1.write(2250);
        //tone(buzzer, 440);
        delay(1000);
        //noTone(buzzer);
        //servo1.write(2250);
        //delay(1000);
       
      }
      if (message [i] == 'L')
      {
       digitalWrite(bluePin,HIGH);
       Serial.write(", BLUE LED ON");
       setColor(0, 0, 255);
       //servol.write (1250);
       delay(1000);
       }
       if (message [i] == 'M')
      {
       digitalWrite(bluePin,HIGH);
       Serial.write(", AQUA LED ON");
       setColor(0, 255,255 );
       //servol.write(900);
       delay(1000);
      }
      
    }
    Serial.println();
  }
}

Do ignore the 'L' and 'M' sections as they were testers.

What I'm running issues into is the 'K' section. Currently, without the buzzer on, the code runs smoothly. e.g. when the condition is met, the rgb led turns green and the servo rotates as instructed. when condition 'J' is met, the led turns red and the servo turns back (i need to work on how much the servo rotates).

However, when I put the codes for the buzzer, my servo only rotates ONE time for both the red and green, aka, it doesn't keep rotating back and forth when the conditions are met.

The leds still work and so does the buzzer. I feel that the codes for the buzzer are causing the issue, how can I fix this?

You have all kinds of Serial.print() for messages, but I see NONE used to display the values used in any "if" statements. When you see those values, then you can begin to debug your program.

You have "if" statements combined with Serial.read, so you can't see what is being read. Quick way to add bugs to a program. Make any "if" with a serial read or and input a separate statement. Then you can print the values before doing the "if" compare.

Paul

Paul_KD7HB:
Make any "if" with a serial read or and input a separate statement.

Paul

I think I need further clarifications for this. Should I add a line of Serial.print() on the end of every 'if' statements before the program jumps to the next statement?

edit: if by values, you mean the actual numbers, they are being read and displayed on the transmitter board almost flawlessly. My receiving board (this board) is not meant to display any numerical values.

My receiving board (this board) is not meant to display any numerical values.

But it might temporarily have to in order to help debugging

thenecniv:
I think I need further clarifications for this. Should I add a line of Serial.print() on the end of every 'if' statements before the program jumps to the next statement?

edit: if by values, you mean the actual numbers, they are being read and displayed on the transmitter board almost flawlessly. My receiving board (this board) is not meant to display any numerical values.

Read the value and store it into a variable. Serial.print the variable. Then use the variable in the "if" statement. Otherwise you NEVER see what is actually being tested. Only able to guess, and that is no way to debug a program..

Paul

So, I've made new lines of serial.print() for the 'J' and 'K' sections.

I've got value readings for 'J' but 'K' is not displaying any values.

i used the analogRead(pin) function to help me identify the values.

Funny thing is that even without the values, the servo without the buzzer works. The minute I put my buzzer in, my servo fails to work properly.

or I'm just terrible at debugging and coding in a whole. Help?

edit: no value due to me missing the serial.println(), but the problem remains. I cant get it to work simultaneously!

Please post the code as it is now

Which board? For most boards, tone() uses timer2. Based on the name of the servo library, it also uses timer2.

I'm quite sure that that is the cause of your problem.

sterretje:
Which board? For most boards, tone() uses timer2. Based on the name of the servo library, it also uses timer2.

I'm quite sure that that is the cause of your problem.

I am currently using the Arduino Uno.

So if that is the problem, I would just have to find another servo library to make this work?

UKHeliBob:
Please post the code as it is now

#include <VirtualWire.h>

#include <ServoTimer2.h>
// a buffer to store the incoming messages
byte message[VW_MAX_MESSAGE_LEN]; 
// the size of the message
byte messageLength = VW_MAX_MESSAGE_LEN;

int ServoPin = 3;
ServoTimer2 servo1;
const int buzzer = 9;

int val = 0;
int ans = 0;

int redPin = 7;
int greenPin = 5 ;
int bluePin = 6 ;

//int ServoPin = 3;
//ServoTimer2 servo1;

void setup()
{
  // Initialize the serial monitor
  Serial.begin(9600);
  Serial.println("Device is ready");
  
  // Initialize the IO and ISR
  vw_setup(2000); // Bits per sec
  vw_rx_start(); // Start the receiver

  // set led pin as an output 
  //pinMode(ledPin, OUTPUT);
  servo1.attach(ServoPin);
  pinMode(redPin, OUTPUT);
  //Serial.println ("Check 1");
  pinMode(greenPin, OUTPUT);
  //Serial.println ("Check 2");
  pinMode(bluePin, OUTPUT);
  //Serial.println ("Check 3");
  pinMode(buzzer, OUTPUT);
}

void setColor(int red, int green, int blue)
{
  digitalWrite(redPin, red);
  digitalWrite(greenPin, green);
  digitalWrite(bluePin, blue);  
}

void loop()
{
  //setColor(255, 0, 0);  // red
  //delay(1000);
  //setColor(0, 255, 0);  // green
  //delay(1000);
  //setColor(0, 0, 255);  // blue
  //delay(1000);
  /*setColor(255, 255, 0);  // yellow
  delay(1000);  
  setColor(80, 0, 80);  // purple
  delay(1000);
  setColor(0, 255, 255);  // aqua
  delay(1000); */
  
  if (vw_get_message(message, &messageLength)) 
  {
    Serial.print("Received: ");
    for (int i = 0; i < messageLength; i++)
    {
      Serial.write(message[i]);
      if(message[i]=='J')
      {
        //digitalWrite(ledPin,HIGH);
        digitalWrite(redPin, HIGH);
        Serial.write(",  RED LED ON");
        setColor(255, 0, 0);
        servo1.write(750);
        val = analogRead(ServoPin);
        Serial.println(val);
        delay(1000);
      }
        else if (message [i] == 'K') {
          digitalWrite(greenPin,HIGH);
        Serial.write(", GREEN LED ON");
        setColor(0, 255,0 );
        servo1.write(2250);
        ans = analogRead(ServoPin);
        //tone(buzzer, 440);
        //delay(1000);
        //noTone(buzzer);
        Serial.println(ans);
        delay(2000);

        digitalWrite(redPin, HIGH);
        Serial.write("Door Close");
        setColor(255,0,0);
        servo1.write(750);
        
        }
      

      /*if(message[i]=='K')
      {
        //digitalWrite(ledPin,LOW);
        digitalWrite(greenPin,HIGH);
        Serial.write(", GREEN LED ON");
        setColor(0, 255,0 );
        servo1.write(2250);
        /*tone(buzzer, 440);
        delay(1000);
        noTone(buzzer);
        ans = analogRead(ServoPin);
        Serial.println(ans);
        //val = analogRead(ServoPin);
        //val = analogRead(ServoPin);
        delay(1000);
       
      }
      if (message [i] == 'L')
      {
       digitalWrite(bluePin,HIGH);
       Serial.write(", BLUE LED ON");
       setColor(0, 0, 255);
       servo1.write(1500);
       delay(1000);
       }
       if (message [i] == 'M')
      {
       digitalWrite(bluePin,HIGH);
       Serial.write(", AQUA LED ON");
       setColor(0, 255,255 );
       //servol.write(900);
       delay(1000);
      } */
      
    }
    Serial.println();
  }
}

this is what I am doing now. I think I'm doing it wrong. I edited the codes quite a bit to get the servo to turn on its own after a moment and stop. Buzzer is still commented out

But the reason you're using ServoTimer2 is because VirtualWire uses timer1 which the normal Servo library uses. If you have conflicts on both 1 and 2 that leaves you a bit short of possible timers to use on a UNO.

There is apparently a TimerFreeTone library which removes the need for any timers for beeping but I've never used it.

Steve

There are a few ways to solve this, but you have to test thoroughly.

Easiest solution is to use a 32U4 based board (Leonardo, Micro); the tone library will use timer3 in that case.

Second solution is to use a Mega and modify the tone 'library' to use one of the other timers.

Sticking with your current board, you can attempt to make use of timer0 for the tone 'library'; I'm reasonably sure that it will work without ill side effects, but you have to do the thorough testing (timer0 is also used for millis() etc); you will loose PWM on pin 6 (if I'm not mistaken). Below is what I would try based of my understanding of the code in tone.cpp.

Find the file tone.cpp and modify the below section (lines 115..124 on my system). Make a backup of that file so you can easily restore if needed. You need admin rights to modify it.

#else

#define AVAILABLE_TONE_PINS 1
#define USE_TIMER2

// Leave timer 0 to last.
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };

#endif

to

#else

#define AVAILABLE_TONE_PINS 1
#define USE_TIMER0

// Leave timer 0 to last.
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 0 /*, 1, 2 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };

#endif

No guarantees that nothing else breaks, modify at own risk.

Note that this change will affect all old code and future code if you compile them (again); so if you e.g. had an old sketch that used PWM on pin 6 and the tone, that will probably no longer work.