Go Down

Topic: Odd Problems with Audio Tone Generation on DUE (Read 1 time) previous topic - next topic

srnet

Dec 16, 2016, 08:37 am Last Edit: Dec 16, 2016, 08:44 pm by srnet Reason: Typos
The code posted below uses a I/0 pin to generate tones and send a string of ASCII data as AFSK RTTY so it can by uploaded with a PC program called FLDIGI and then onto the Internet for tracking purposes. Its a sub-routine of a larger LoRa tracker receiver program. The AFSK RTTY is 200 Baud serial data, 1000hz for a bit value of 0, 1500hz for a 1. There is an initial lead in tone (1500hz) then the actual data.

The code as posted works just fine with a stable decode. A spectrum analyser screen shows a relatively clean 1500Hz lead in tone (for a square wave) which is sent by the 'start_AFSK_RTTY() ' at the beginning, see the 'GOOD' spectrum analyser image attached.

However if I do certain things that actually don't alter the function of the code but affect its length and or maybe position in memory the tone generation fails, the previous nice clean audio tone sounds awful. Very scratchy, see the 'BAD' image.

For instance if at the very end of the void SendAFSKRTTY(byte chartosend) routine (which sends the actual characters) there are two stop bits sent. If I add an extra stop bit there should be no affect on the code function but it does make the code segment a bit longer.  I changed the number of stop bits from 2 to 3 by adding an extra line thus;

From;

TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);  //send a Stop bit  
TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);  //send a Stop bit

To;

TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);  //send a Stop bit  
TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);  //send a Stop bit
TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);  //send a Stop bit

If I do other benign changes to the code, the initial tones also change from GOOD to BAD. I dont think its a problem with the TimerFreeTone library, I get similar issues when I bit bang the tones with my own code.

If I take out the Serial.write(chartosend); that echoes the sent character to terminal the lead in tone messes up big time, see the VERYBAD picture.

The code changes described (that mess up the initial lead in tone) are to bits of code that are not even executed until after the lead in tone.  

Any ideas why a bit of code, yet to be executed, affects the operation of a previous bit of code ?




Code: [Select]
//AFSK_RTTY2.h
/*
******************************************************************************************************

Easy Build LoRaTracker Programs for Arduino DUE

Copyright of the author Stuart Robinson - 13/12/2016

http:www.LoRaTracker.uk

******************************************************************************************************
*/

/*
******************************************************************************************************
Sends data as AFSK RTTY at 200 baud, 7 bit, 1 start bit, 2 stop bits and no parity. Tones are 1000Hz
for a 0 bit and 1500hz for 1 bit.

Can be used for transmitting ASFK RTTY over the air or for a direct link to a PC sound card

This program needs the TimerFreeTone library, the normal Arduino Tone does not work on a DUE

******************************************************************************************************
*/

const unsigned int AFSKrttybaud = 4;                              //tone length in mS
const unsigned int leadinmS = 2000;                               //number of mS of lead in tone
const unsigned int tonehigh = 1500;
const unsigned int tonelow = 1000;


void start_AFSK_RTTY()
{
  TimerFreeTone(Audio_Out, tonehigh, leadinmS);                  //lead in is high tone
}

void SendAFSKRTTY(byte chartosend)
//send the byte in chartosend as AFSK RTTY, assumes mark condition (idle) is already present
//Format is 7 bits, no parity and 2 stop bits
{
  byte numbits;

  digitalWrite(PLED1, HIGH);
  Serial.write(chartosend);
  TimerFreeTone(Audio_Out, tonelow, AFSKrttybaud);                 //start bit
  
  for (numbits = 1;  numbits <= 7; numbits++)                     //send 7 bits, LSB first
  {
    if ((chartosend & 0x01) != 0)
    {
      TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);            //send a 1 bit, high tone
    }
    else
    {
      TimerFreeTone(Audio_Out, tonelow, AFSKrttybaud);           //send a 0 bit, low tone
    }

    chartosend = (chartosend / 2); //get the next bit

  }

  digitalWrite(PLED1, LOW);

  TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);               //send a stop bit, high tone
  TimerFreeTone(Audio_Out, tonehigh, AFSKrttybaud);                 //send a stop bit, high tone
}






No PMs please, they dont get answered.

J-M-L

#1
Dec 16, 2016, 01:05 pm Last Edit: Dec 16, 2016, 01:14 pm by J-M-L
Well you need to share the real FULL code showing the behavior - the bug is most likely not in the snippet there... + info about IDE Version and actual libraries: E.g. Have you the latest library ? v1.5 was Released 09/12/2016 -> Fixed problem with latest release of the Arduino IDE which caused the library to totally stop functioning. Adjusted note duration to not fail on timer rollover. Now delays for note duration when frequency or volume are zero.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

srnet

Well I had checked a few days ago for an update to TimerFreeTone, but missed it, so I was almost 7 days out of date.

The problem is the same with the updated library, and as I said I get similar issues when I bit bang the tones with my own code when I checked to see if there was a problem with TimerFreeTone.

The full program is quite large, but I had reduced it to a bare minimum already to try and identify the problem, the AFSK_RTTY2.h file is as already posted, this is the rest of the code;


Code: [Select]

#define Audio_Out  36
#define PLED1  8

#include <TimerFreeTone.h>
#include "AFSK_RTTY2.h"

void loop()
{
  byte i;
  char j;
 
  start_AFSK_RTTY();
   
  for (i = 0; i <= 50; i++)
  {
    SendAFSKRTTY('U');
  }
 
  delay(2000);
}

void setup()
{
  pinMode(PLED1, OUTPUT);                      //setup pin for PCB LED
  Serial.begin(38400);                           //setup Serial console ouput
}


No PMs please, they dont get answered.

srnet

I will add that the problem is evident on a scope too.

I can see when the tone is BAD that the low part of the tone can vary by up to approx 25% but is not consistent at that value. The effect of this would be to produce a range of frequencies, rather than a single consistent tone.

No PMs please, they dont get answered.

srnet

And before anyone asks, I get the same problem with another DUE base.

I dont get the problem when I plug the same hardware shield into an ATMEGA2560 base.
No PMs please, they dont get answered.

bobcousins

Do you really need to use TimerFreeTone? The problem with any type of bitbanging is that determinancy can be screwed by interrupts. The Due has 9 hardware timers, plus PWM, plenty of ways to generate a solid frequency without relying on bitbanging.
Please ask questions in the forum so everyone can benefit. PM me for paid work.

srnet

I dont have to use TimerFreeTone, or indeed manual bit banging, but it does make the code simpler and easier to understand.

Even whilst there may be 'better' methods of doing the tones, there is definetly something weird going on when small changes to the length and or position of the code in memory produces code that does not function as intended.

No PMs please, they dont get answered.

J-M-L

can you explain how you acquire and what we see in your screen grabs? (and why you think some are good and some are not)?
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

srnet

The DUE pin goes to a 3.5mm jack socket via a 47K resistor and 100nF cap.

The jacksocket is plugged into PC sound card, and the screen grabs are for a bit of software that acts as a spectrum analyser.

If the 'tone' being produced is stable at 1500hz, then since its a square wave you would expect (on the spectrum analyser screen) a single peak at the fundamental plus peaks of a series of diminishing harmonics, this is clearly shown in the GOOD picture.

In the BAD picture there is no single sharp peak, its all a bit of mush. This is caused by the tone varying in frequency rather than bieng stable at 1500hz.

No PMs please, they dont get answered.

Go Up