Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: 8 bit Frequency Shift Keying Teensy 3.6

  1. #1
    Junior Member
    Join Date
    Nov 2016
    Posts
    2

    8 bit Frequency Shift Keying Teensy 3.6

    Hey ya'll

    So I'm running into some problems I haven't been able to figure out. I am generating 8 sine waves, each sine representing a bit in a char. I'll change the amplitudes of each sine waveform, hold it for 5 ms, and then encode the next char. I also synth a DC waveform, this waveform's amplitude toggles between .6 and -.6 between chars. Right now I am just outputting the audio from a Teensy 3.6 via USB to my Mac. I can record the audio with Audacity. Later, when I'm happy with the signals I'll switch over to the Teensy Audio Shield.

    I actually have this working... sort of. Their are some quirky things going on. For example; the DC waveform is only supposed to be on the L-channel, however is shows up on L&R. If i don't have an AudioOutputI2S object declared, there is no audio output through USB?? Adding other variables to measure the delay in micros() between encoding chars completely changes the audio signal.

    Here are my instantiations of the audio objects. The AudioOutoutI2S is declared, but never used. Nothing will output through USB if its not there.

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    AudioSynthWaveformSine   mySin[7];          
    AudioSynthWaveformDc     square_clk;          
    AudioMixer4              mixer1;        
    AudioMixer4              mixer2;         
    AudioMixer4              mixer3;
    AudioOutputI2S           i2s2_output;          
    AudioOutputUSB           usb1;
    
    AudioConnection          patchCord1(mySin[0], 0, mixer1, 0);
    AudioConnection          patchCord2(mySin[1], 0, mixer1, 1);
    AudioConnection          patchCord3(mySin[2], 0, mixer1, 2);
    AudioConnection          patchCord4(mySin[3], 0, mixer1, 3);
    AudioConnection          patchCord5(mySin[4], 0, mixer2, 0);
    AudioConnection          patchCord6(mySin[5], 0, mixer2, 1);
    AudioConnection          patchCord7(mySin[6], 0, mixer2, 2);
    AudioConnection          patchCord8(mySin[7], 0, mixer2, 3);
    AudioConnection          patchCord9(mixer1, 0, mixer3, 0);
    AudioConnection          patchCord10(mixer2, 0, mixer3, 1);
    AudioConnection          patchCord11(square_clk, 0, usb1, 0);
    AudioConnection          patchCord12(mixer3, 0, usb1, 1);
    Click image for larger version. 

Name:	Screen Shot 2017-02-05 at 3.50.39 PM.png 
Views:	52 
Size:	54.1 KB 
ID:	9616

    Set things up

    Code:
    //unsigned long delay_u = 0;
    //unsigned long time_u = 0;
    char c[] = "hello world 123";
    int count = 0;
    int clk = 1;
    int my_freq[] = {8E3, 9E3, 10E3, 11E3, 12E3, 13E3, 14E3, 15E3};
    
    void setup() {
    
      AudioMemory(50);
    
      // Assign a freq and amp to each sin.
      AudioNoInterrupts();
      for(int i=0; i<8; i++){
        mySin[i].frequency(my_freq[i]);
        mySin[i].amplitude(0);
      }
      AudioInterrupts();
    
      delay(1000);
    }
    The unsigned long delay and time are used to measure the delay between chars, I have them commented because they were screwing things up. "hello world" is just repeated over and again, there is a 5 char delay between each repeat.

    The Loop

    Code:
    void loop() {
    
      //time_u = micros();
    
      int len = sizeof(c);
      if(count < len+5){
        count++;
      }else {
        count = 0;
      }
    
      if( count < len ){
        char key = c[count];
        AudioNoInterrupts();
    
        // Toggle Clock
        if(clk == 1){
          clk = 0;
          square_clk.amplitude(-.6);
        } else {
          clk = 1;
          square_clk.amplitude(.6);
        }
        // Toggle Sins
        for (int i = 0; i<8; i++){
          if(bitRead(key, 7-i) == 1){
            mySin[i].amplitude(.6);
          } else {
            mySin[i].amplitude(0);
          } // end else if
        } // end for bit read
        
        AudioInterrupts();
      }
      
      
      if(count >= len){
        // No Data  
        AudioNoInterrupts();
        if(clk == 1){
          clk = 0;
          square_clk.amplitude(-.6);
        } else {
          clk = 1;
          square_clk.amplitude(.6);
        }
        for(int i=0;i<8;i++){
          mySin[i].amplitude(0);
        } //end for
        AudioInterrupts();
      }
        
    
    
      //delay_u = micros() - time_u;
      //delayMicroseconds(5E3-dealy_u)
      delay(5);
      
    } // end loop
    The waveform

    Click image for larger version. 

Name:	Screen Shot 2017-02-05 at 3.34.30 PM.jpg 
Views:	14 
Size:	69.9 KB 
ID:	9615

    So you can see the clock is on both R&L channels and the duration of the clock isn't as good as I would like it to be. However, the clk period is consistent with the period of the data. So I can still decode it.

    Subtracting out the delay between encoding each char doesn't work either. It did't fix the clk period and for whatever reason it added the clk and sin waveforms...

    Any good ideas? I'm out lol. I realize I am doing something the library wasn't made to do.

    Thanks for the help! I love these boards!

    FYI the purpose of this is to encode data into the audio channels of recording devices.

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    830
    Code:
    AudioSynthWaveformSine   mySin[7];
    That should be 8.

    Pete

  3. #3
    Junior Member
    Join Date
    Nov 2016
    Posts
    2
    Thanks, you are absolutely right about that. So now my MSB is working. I guess I could have been changing things in memory I shouldn't have been?

    Same problems remain. Not a game changer if I can't them fixed, its just a bit annoying.

    DC wave form is still on both channels, and AudioOutputI2S still needs to be declared in order to work.

    Click image for larger version. 

Name:	Screen Shot 2017-02-05 at 5.05.53 PM.jpg 
Views:	9 
Size:	67.0 KB 
ID:	9617

    Frequency spectrum of 'e'. Looks good.

    Click image for larger version. 

Name:	Screen Shot 2017-02-05 at 5.06.49 PM.jpg 
Views:	11 
Size:	132.5 KB 
ID:	9618

    Printing out what bit in a char is assigned to a sine waveform.

    Click image for larger version. 

Name:	Screen Shot 2017-02-05 at 5.09.27 PM.png 
Views:	11 
Size:	24.0 KB 
ID:	9619

    Thanks

  4. #4
    Senior Member Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    4,250
    Quote Originally Posted by drewski View Post
    d AudioOutputI2S still needs to be declared in order to work.
    A quote from https://www.pjrc.com/teensy/gui/?info=AudioOutputUSB:
    "USB input & output does not cause the Teensy Audio Library to update. At least one non-USB input or output object must be present for the entire library to update properly."

  5. #5
    Senior Member bmillier's Avatar
    Join Date
    Apr 2016
    Location
    Halifax, N.S. Canada
    Posts
    108
    The fact that the i2s output has to be included even if you are only using USB is a known "bug", or "feature" of the audio library. USB won't work on its own - you need some other output like DAC or I2S to actually trigger the audio library updates.
    I am wondering why you are generating the clock in your sketch, instead of just including a synth object of type WAVEFORM and setting its type to WAVEFORM SQUARE? You then set its freq and amplitude, and it will give a steady clock. If you need to gate the clock on and off between characters, for example, you can just set its amplitude to zero for that time. The synth waveform object will generate a steady square wave of 50% duty cycle.You can also use the phase setting to start the waveform at a specific time if you need this feature.
    I don't know why your DC waveform object, which is definitely only wired to one channel from the looks of your code, is showing up in both channels. I've used audio lib USB output, but only for a mono signal, and wouldn't have noticed something like this, if it is indeed. a bug in the library ( which I doubt).
    Brian

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •