Go Down

Topic: tone() and reading data from serial (Read 1 time) previous topic - next topic


Nov 03, 2012, 01:52 pm Last Edit: Nov 03, 2012, 03:19 pm by acid Reason: 1
In my sketch main loop I used SoftwareSerial in order to read data from gps.

void loop()  
 while (nss.available())
   if (gps.encode(nss.read()))
Also I have timer ISR, which is called every second or so, where I engage buzzer

 tone(8, 1000, 200);
 // digitalWrite(9, 1); delay(200); digitalWrite(9, 0);

The problem is, when I hear the tone and at the same time there is an incoming gps data, the tone is corrupted. When data is finished the tone is clear. So somehow serial input and tone are interfering with each other. In other words, if I just comment nss.begin(9600); then tone is clear.


Below is the full code:
Code: [Select]

#include <avr/io.h>
#include <avr/interrupt.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps;
SoftwareSerial nss(3, 4);

void setup()  {

  // initialize Timer1
  cli();          // disable global interrupts
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B

  // set compare match register to desired timer count:
  OCR1A = 15624;

  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);

  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);

  // enable timer compare interrupt:
  TIMSK1 |= (1 << OCIE1A);

  // enable global interrupts:

  tone(8, 1000, 500);

void loop() 
  float flat, flon, speedkmh;
  unsigned long age;
  unsigned short sat;
  while (nss.available())
    if (gps.encode(nss.read()))
        gps.f_get_position(&flat, &flon, &age);
        sat = gps.satellites();
        speedkmh = gps.f_speed_kmph();
        if(flat != TinyGPS::GPS_INVALID_F_ANGLE && flon != TinyGPS::GPS_INVALID_F_ANGLE && age != TinyGPS::GPS_INVALID_AGE
            && sat != TinyGPS::GPS_INVALID_SATELLITES && speedkmh != TinyGPS::GPS_INVALID_SPEED)
          Serial.println("Something is wrong...");

How can I solve this?


You need to post all your code not just a small part ( and post it within code tags)



When you pass a duration to tone() it becomes a blocking call, meaning it does not return until the duration has passed. Since you're calling it within an ISR, this prevents anything else from happening during that time.

I suggest you completely abandon use of an ISR to trigger this, and use the technique demonstrated in 'blink without delay' to start and stop the tone at regular intervals from within loop().

Go Up