Go Down

Topic: stqc decoder - reading frequency (Read 239 times) previous topic - next topic

zlog

May 15, 2019, 09:29 pm Last Edit: May 15, 2019, 09:31 pm by zlog
Hi!
I need to do stqc decoder on Arduino Mega2650.
I've tried this code:
Code: [Select]
#define SOUND_PIN 47

int Htime, Ltime, prescale = 1;
float Ttime, frequency;

void setup() {
  pinMode(SOUND_PIN, INPUT);
  Serial.begin(9600);
  Serial.println("Frequency: ");
}

void loop() {
  Htime=pulseIn(8,HIGH);
  Ltime=pulseIn(8,LOW);
  
  Ttime = Htime+Ltime;
  
  frequency=1000000/Ttime;
  frequency=frequency*prescale;
  Serial.print(frequency);
  Serial.println(" Hz");
}

This code gived me frequency ifinity.
I've tried to use FreqCount and FreqMeasure, but they wasn't working as I expected.

Here is code, which reacts playing audio, but shows to small frequency:
Code: [Select]
#define SOUND_PIN 47

void setup() {
  pinMode(SOUND_PIN, INPUT);
  Serial.begin(9600);
  Serial.println("Frequency :");
}

void loop() {
  long number=0, time1=micros();
  do
  {
    if (digitalRead(SOUND_PIN)==HIGH) {
      while (digitalRead(SOUND_PIN)==HIGH) {}
      number++;
    }
  }while (micros()<(time1+1000000));
  Serial.print(number);
  Serial.println(" Hz");
}


I'm using LCD Keypad Shield so some pins are unavailable.
If some thing is wrong in code, I want to understand this correct one.
For exemple, I don't understand this code (this one isn't working too):
Code: [Select]
// input on pin D47 (T5)
volatile unsigned long timerCounts;
volatile boolean counterReady;
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms)
{

  counterReady = false;         // time not up yet
  timerPeriod = ms;             // how many 1 ms counts to do
  timerTicks = 0;               // reset interrupt counter
  overflowCount = 0;            // no overflows yet

  // reset Timer 2 and Timer 5
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR5A = 0;            
  TCCR5B = 0;  

  // Timer 5 - counts events on pin D47
  TIMSK5 = bit (TOIE1);   // interrupt on Timer 5 overflow

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

  TCNT2 = 0;    
  TCNT5 = 0;      // Both counters to zero

  // Reset prescalers
  GTCCR = bit (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
  // start Timer 5
  // External clock source on T4 pin (D47). Clock on rising edge.
  TCCR5B =  bit (CS50) | bit (CS51) | bit (CS52);

}  // end of startCounting

ISR (TIMER5_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER5_OVF_vect


//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect)
{
  // grab counter value before it changes any more
  unsigned int timer5CounterValue;
  timer5CounterValue = TCNT5;  // see datasheet, (accessing 16-bit registers)

  // see if we have reached timing period
  if (++timerTicks < timerPeriod)
    return;  // not yet

  // if just missed an overflow
  if (TIFR5 & TOV5)
    overflowCount++;

  // end of gate time, measurement ready

  TCCR5A = 0;    // stop timer 5
  TCCR5B = 0;    

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;    

  TIMSK2 = 0;    // disable Timer2 Interrupt
  TIMSK5 = 0;    // disable Timer5 Interrupt

  // calculate total count
  timerCounts = (overflowCount << 16) + timer5CounterValue;  // each overflow is 65536 more
  counterReady = true;              // set global flag for end count period
}  // end of TIMER2_COMPA_vect


void setup ()
{
  Serial.begin(9600);
  Serial.println("Frequency Counter");
}

void loop ()
{
  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;    
  
  startCounting (500);  // how many ms to count for

  while (!counterReady)
     { }  // loop until count over

  // adjust counts by counting interval to give frequency in Hz
  float frq = (timerCounts *  1000.0) / timerPeriod;

  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  Serial.print ("Frequency: ");
  Serial.println ((unsigned long) frq);
  
  // let serial stuff finish
  delay(200);

}

In this one, I don't understand these: TCCR0A, TCCR0B and so on.

I think, the problem is in circuit too.
In attachments circuit image.
Sorry for mistakes.
Thanks in advance for any help.

Grumpy_Mike

Quote
In this one, I don't understand these: TCCR0A, TCCR0B and so on.
These are timer / counter registers. They control the action of the timers. Look in the processor's data sheet to see what they do. A word of warning, the timer / counters are different on the Uno to the Mega code using them on one processor will not work on the other. Also the Uno has three timer / counters where the Mega has six of them.

What is stqc? I did try googling but got no clear idea.

Quote
I think, the problem is in circuit too.
Not much of a circuit with no labels to show what is going on but it looks wrong. This is the OP's circuit:-


Is the signal an input or output, it is going to a digital pin so I am assuming it is a digital signal, or at least one that goes between at least 0.7V and 3.7V. If it is an audio signal then why put it in a digital pin? Also the negitave signal part of the audio can damage your Arduino so that needs a protection diode to clamp the signal to the rail.

 
Quote
This code gave me frequency infinity.
( corrected spelling mistakes please say if this resulted in the wrong words )
That will happen if your signal never went high enough to trigger the pulse in start criteria, which suggest that you are feeding an audio signal into this pin.

But without solid information of what you are doing an why some of this is just guess work.

zlog

Quote
What is stqc?
Here is link to someone's stqc project for linux (here is what stqc is): https://github.com/sq5bpf/multimon-ng-stqc/blob/master/README_STQC

Quote
If it is an audio signal then why put it in a digital pin?
I don't now much about circuits. I've done this, because in source code it was a digital pin.

In attachment is exemple of sound encoded in stqc (please change .png to .mp3)

Grumpy_Mike

While that link describes what tones are use for what sequence of numbers, nowhere does it say what it actually is and how / who uses it.

From the bit at the end:- "73 de Jacek Lipkowski" I assume it is something to do with ham radio as "73" is ham short hand for "best wishes" so I am assuming it is some sort of ham radio communications. Also the bit that says:-
Quote
Note: the english version is intentionally short, as this system is used
probably only in Poland.
Might explain why there is very little understandable information about it.

So if you are trying to decode this stuff you need a better input circuit. The audio should be passed through a transistor first, or even better put it through a comparitor so you get a good logic level squared off signal that you stand a chance of measuring.

There are basically two ways of measuring a simple frequency like this:-
1) Time how long one cycle takes. That is the time between successive rising edges of the signal.
2) Measure for a fixed period of time and count the number of rising ( or falling ) edges you see.

Method 1 is used when the frequencies are low with long duration.
Method 2 is for longer duration tones.

Google :- Arduino frequency measurement

zlog

#4
May 16, 2019, 10:10 pm Last Edit: May 16, 2019, 11:03 pm by zlog
Oh, sorry.
I'm from Poland so I was reading only Polish version and I thought the same is in Englisch version.

This is used by firefighters or to alarm people about any cataclysm in their area.
This can be received by any transceiver and by jack to decoder.

I was asked to do arduino as decoder, so I need to get frequency some how.

Quote
Method 1 is used when the frequencies are low with long duration.
Method 2 is for longer duration tones.
I'm a little bit confused now.
Is there any method for short duration (I think 100ms isn't long duration)?

Quote
Google :- Arduino frequency measurement
I was searching like this, but any of codes wasn't working.

So, should this look something like this in atachment?
And what should be the values of capacitor and resistor?

Grumpy_Mike

Quote
So, should this look something like this in atachment?
No nothing like this.

In reply #3 I said:-
Quote
The audio should be passed through a transistor first, or even better put it through a comparitor so you get a good logic level squared off signal that you stand a chance of measuring.
So why do you think totally ignoring this advice is a good idea?

Quote
I was searching like this, but any of codes wasn't working.
That is because you have not got a signal to measure. I told you this in reply#1. Why are you not paying any attention? Am I wasting my time offering you advice?

zlog

#6
May 17, 2019, 08:42 pm Last Edit: May 17, 2019, 08:44 pm by zlog
Quote
Why do you think totally ignoring this advice is a good idea?
It was mistake in reading, sorry.

Quote
That is because you have not got a signal to measure. I told you this in reply#1.
So why in the same situation second code, that I pasted here, reacts for playing audio (but shows to low frequency)? When other dosen't react and gives infinity (in first code) or random numbers (even audio isn't playing)?

Go Up