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

Thread: TEA5767 radio module on teensy?

  1. #1

    TEA5767 radio module on teensy?

    Heya!

    I just learned about these cool looking small FM radio modules: http://playground.arduino.cc/Main/TEA5767Radio

    I was wondering whether that code library would work on a Teensy?

    I've ordered some anyway (I can always just use an arduino), so I'm happy to test if no one has done so already. I'd like to make a USB MIDI controlled radio station sequencer, so if I can surmount the first obstacle of controlling the radio with a teensy then I'll post my progress here.

    cheers,

    yann

  2. #2
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    radio station sequencer -
    does what?

  3. #3
    Quote Originally Posted by stevech View Post
    radio station sequencer -
    does what?
    I'm thinking about assigning each midi note value a radio frequency. that way I can program drum patterns in Max/MSP or Ableton or something and output them through USB MIDI to the Teensy/TEA5767, creating constantly shifting sequences that change along with the radio stations.

    I could also just 'play' the stations using a midi keyboard, which would be fun!

    So yeah, I'd like to use a Teensy for this, because it's so easy to turn it into a USB MIDI device.

  4. #4
    Member
    Join Date
    Jun 2013
    Location
    Southern Colorado
    Posts
    66

    T3 shop clock/radio

    The TEA5767 works just fine with the Teensy3.x. Here is the complete program for a shop clock/radio that I developed using a Teensy 3.0. It uses a Nokia 5110 display and a mechanical encoder from SparkFun https://www.sparkfun.com/products/9117. The program is a patchwork of sloppy code stitched together with good intentions. It includes temperature compensation for the Teensy RTC and a tweaked patch of code for the encoder. Again, the code is a bit sloppy and disorganized but it is reliable and works very well. I have not put everything in an enclosure yet so it is laced together on a small section of my bench and has worked great for over a year now.

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


    #include <SPI.h>
    #include <Wire.h>
    #include <EEPROM.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_PCD8544.h>
    #include <Time.h>

    // These Adafruit(#338 blue board) Nokia 5110
    // displays use SPI to communicate, 4 or 5 pins
    // are required to interface.
    // MCU pins -- Nokia pins
    // pin 7 - Serial clock out (SCLK)
    // pin 6 - Serial data out (DIN)
    // pin 5 - Data/Command select (D/C)
    // pin 3 - LCD chip select (CS)
    // pin 4 - LCD reset (RST)
    // init display
    Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 3, 4);

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

    boolean toggle = false;
    int SDIO = A4;
    int SCLK = A5;
    int channel;
    int volume;
    int myhour;
    int mutePin = 1;
    char tempString[10];
    float fchannel;

    const int encoderPin21 = 21; // encoder pin 1
    const int encoderPin22 = 22; // encoder pin 2

    #define INT_Pin21 21 // interrupt on #21
    #define INT_Pin22 22 // interrupt on #22

    //Volatile variables are needed if used within interrupts
    volatile int lastEncoded = 0;
    volatile long encoderValue = 0;

    volatile int goodEncoderValue;
    volatile boolean updateStation = false;

    const boolean UP = true;
    const boolean DOWN = false;
    volatile boolean stationDirection;

    /************************************************** ************************************************** */
    byte frequencyH = 0;
    byte frequencyL = 0;
    unsigned int frequencyB;
    double frequency = 0;
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void setup()
    {
    //setTime(hr,min,sec,day,mnth,yr)
    //use 24 hour time in the above
    //format with midnight being 0 hours

    //PROCEDURE: un-comment the two lines below and
    // upload the program. Then re-comment
    // the same lines and upload the program again.

    //setTime(14,58,0,23,9,14);
    //Teensy3Clock.set(now());

    hourFormat12();

    // set the Time library to use Teensy 3.0's RTC to keep time
    setSyncProvider(getTeensy3Time);

    display.begin();
    analogWrite(9,25); // turn on and modulate display backlight
    display.setContrast(60); // set contrast
    display.clearDisplay(); // clears the screen and buffer


    Wire.begin();

    read_channel_from_EEPROM();
    if(channel <= 875 || channel >= 1081)
    { channel = 981;}
    setFrequency();

    update_display();

    analogReadRes(12);
    analogReadAveraging(8);

    pinMode(mutePin,INPUT_PULLUP); // to read encoder momentary push switch

    // both pins on the rotary encoder are inputs and pulled high
    pinMode(encoderPin21, INPUT_PULLUP);
    pinMode(encoderPin22, INPUT_PULLUP);

    //call updateEncoder() when any high/low changed seen
    //on interrupt 0 (pin 2), or interrupt 1 (pin 3)
    attachInterrupt(INT_Pin21, updateEncoder, CHANGE);
    attachInterrupt(INT_Pin22, updateEncoder, CHANGE);

    updateEncoder();
    }
    /************************************************** ************************************************** */

    /************************************************** ************************************************** */
    void loop()
    {
    // interrupt tells us when to update the station
    if(updateStation)
    {
    if(stationDirection == UP) channel += 2;

    else if(stationDirection == DOWN) channel -= 2;

    //Catch wrap conditions
    if(channel > 1079) channel = 875;
    if(channel < 875) channel = 1079;

    setFrequency(); //Goto the new channel
    save_channel(); // save channel to EEPROM
    update_display();

    updateStation = false; //Clear flag
    }
    if(!digitalRead(mutePin))
    {
    delay(100);
    if(!digitalRead(mutePin))
    {
    toggle = !toggle;
    setFrequency();
    update_display();
    }
    while(!digitalRead(mutePin));
    delay(100);
    }
    if(millis() % 200 == 0)update_display();
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void setFrequency()
    {
    frequency = (double)channel/10;
    frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
    frequencyH = frequencyB >> 8;
    frequencyL = frequencyB & 0XFF;

    Wire.beginTransmission(0x60);
    Wire.write(frequencyH);
    Wire.write(frequencyL);
    Wire.write(0xB2); // bit 1 forces mono mode and mutes right channel
    if(!toggle)Wire.write(0x10); // use 0x58 for mute
    else Wire.write(0x58);
    Wire.write((byte)0x00);
    Wire.endTransmission();
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void updateEncoder()
    {
    delayMicroseconds(500);
    int MSB = digitalRead(encoderPin21); //MSB = most significant bit
    int LSB = digitalRead(encoderPin22); //LSB = least significant bit

    int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
    int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

    if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
    {
    stationDirection = DOWN; //Counter clock wise
    encoderValue--;
    }
    if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
    {
    stationDirection = UP; //Clock wise
    encoderValue++;
    }

    lastEncoded = encoded; //store this value for next time

    //Wait until we are more than 3 ticks from previous used value
    if(abs(goodEncoderValue - encoderValue) > 3)
    {
    //The user can sometimes miss an indent by a count or two
    //This logic tries to correct for that
    //Remember, interrupts are happening in the background so encoderValue can change
    //throughout this code

    if(encoderValue % 4 == 0) //Then we are on a good indent
    {
    goodEncoderValue = encoderValue; //Remember this good setting
    }
    else if( abs(goodEncoderValue - encoderValue) == 3) //The encoder is one short
    {
    if(encoderValue < 0) goodEncoderValue = encoderValue - 1; //Remember this good setting
    if(encoderValue > 0) goodEncoderValue = encoderValue + 1; //Remember this good setting
    }
    else if( abs(goodEncoderValue - encoderValue) == 5) //The encoder is one too long
    {
    if(encoderValue < 0) goodEncoderValue = encoderValue + 1; //Remember this good setting
    if(encoderValue > 0) goodEncoderValue = encoderValue - 1; //Remember this good setting
    }

    updateStation = true;
    }
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    time_t getTeensy3Time()
    {
    return Teensy3Clock.get();
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void update_display(void)
    {
    // set up to read a LM335 temperature sensor with 12 bit resolution
    // measured VCC was 3.279 volts so 1 count = .0008 volts. The LM335
    // puts out 10 millivolts per deg. C. It is referenced to absolute
    // zero so 0 degrees C will be 2.73 volts or 3412.5 counts. The next
    // few lines convert the sensor output to degrees C.

    float tmp_snsrC = analogRead(A9);
    tmp_snsrC = (((tmp_snsrC - 3412.5) / 12.5) - 2.7);

    //int tempcomp = abs((25.0 - (int)tmp_snsrC) / 2);
    int tempcomp = abs(25.0 - (int)tmp_snsrC);

    //Serial.println(tempcomp);

    if(tempcomp >= 1) Teensy3Clock.compensate(tempcomp * -1);

    // with Teensy3Clock.compensate(int), a positive number speeds the clock up
    // and a negative number slows the clock down

    fchannel = (float)channel/10;
    sprintf(tempString, "%.1f", fchannel);
    display.clearDisplay(); // clears the screen and buffer

    display.setTextSize(2);
    display.setTextColor(BLACK);
    display.setCursor(0,1);

    if(hour() <= 12 && hour() != 0) myhour = hour();
    if(hour() >= 13) myhour = (hour() - 12);
    if(hour() == 0) myhour = (hour() + 12);

    if(myhour < 10)
    {
    display.print(" ");
    display.print(myhour);
    }

    else display.print(myhour);
    doDigits(minute());

    if(isPM())display.print("PM");
    else display.print("AM");

    display.setTextSize(1);
    display.print("--------------");
    display.print(" RADIO CHANNEL");
    //display.println(tmp_snsrC,1);

    display.setTextSize(2);
    display.setTextColor(BLACK);

    if(toggle)
    {
    display.print(" MUTE");
    display.display(); // sends buffer to display
    }

    else
    {
    if(channel < 1000) display.print(" ");
    else display.print(" ");
    display.println(tempString);
    display.display(); // sends buffer to display
    }
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void save_channel()
    {
    int msb = channel >> 8; // move channel over 8 spots to grab MSB
    int lsb = channel & 0x00FF; // clear the MSB, leaving only the LSB
    EEPROM.write(1, msb); // write each byte to a single 8-bit position
    EEPROM.write(2, lsb);
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    void read_channel_from_EEPROM()
    {
    int msb = EEPROM.read(1); // load the msb into one 8-bit register
    int lsb = EEPROM.read(2); // load the lsb into one 8-bit register
    msb = msb << 8; // shift the msb over 8 bits
    channel = msb|lsb; // concatenate the lsb and msb
    }
    /************************************************** ************************************************** */


    /************************************************** ************************************************** */
    // utility function for digital clock display: prints preceding colon and leading 0
    void doDigits(int digits)
    {
    display.print(":");
    if(digits < 10)display.print('0');
    display.print(digits);
    }
    /************************************************** ************************************************** */
    Last edited by pxgator; 10-02-2014 at 08:12 PM.

  5. #5
    Thanks so much for the info and the code pxgator! I'm happy that it will work with my teensys. With any luck I'll start experimenting next week, I'll post any developments here.

    Cheers!

  6. #6
    Member
    Join Date
    Jun 2013
    Location
    Southern Colorado
    Posts
    66
    Glad you find the info useful amazingrolo. I'm anxious to hear about your progress. I forgot to mention that I did build one of these for my father and put it in an enclosure. It uses the exact program above and it has also worked just fine for over a year now. He mounted it in his shop outside which has open doors and it survives a temperature variation of -20F TO +90F depending on the time of year.

  7. #7
    I've finally gotten started on this project. I'm afraid I haven't yet managed to get a TEA5767 working with my Teensy 3.0.

    I've tried to find the simplest code possible as a starting point, here's what I'm using:
    #include <Wire.h>

    unsigned char frequencyH = 0;
    unsigned char frequencyL = 0;

    unsigned int frequencyB;
    double frequency = 0;
    const int analogInPin = A0;
    void setup()
    {
    Wire.begin();
    frequency = 83.0; //starting frequency
    setFrequency();
    Serial.begin(9600);
    }

    void loop()
    {
    int reading = analogRead(analogInPin);
    //frequency = map((float)reading, 0.0, 1024.0, 87.5, 108.0);

    frequency = ((double)reading * (108.0 - 87.5)) / 1024.0 + 87.5;
    frequency = ((int)(frequency * 10)) / 10.0;

    setFrequency();
    Serial.println(frequency);
    }

    void setFrequency()
    {
    frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
    frequencyH = frequencyB >> 8;
    frequencyL = frequencyB & 0XFF;
    delay(100);
    Wire.beginTransmission(0x60);
    Wire.write(frequencyH);
    Wire.write(frequencyL);
    Wire.write(0xB0);
    Wire.write(0x10);
    Wire.write((byte)0x00);
    Wire.endTransmission();
    delay(100);
    }


    It works perfectly with an Arduino Uno, but with my Teensy 3.0 all I get is hiss. I'm pretty certain I'm wiring it correctly, using Analog5 as my SCL and Analog4 as my SDA. I also don't think it's a powering issue, because it works fine using the 3.3v power from the Arduino.

    Anyone have ideas for what the problem could be?

  8. #8
    Member
    Join Date
    Jun 2013
    Location
    Southern Colorado
    Posts
    66
    Are you using pull up resistors on SCL and SDA ? I'm using 4.7K pull ups on my T3/TEA5767 setups.
    Last edited by pxgator; 10-28-2014 at 02:52 PM.

  9. #9
    Quote Originally Posted by pxgator View Post
    Are you using pull up resistors on SCL and SDA ? I'm using 4.7K resistors on my T3/TEA5767 setup.


    Hey, that seems to have done the trick!
    I just put in a 10k ohm resistor between A4 and 3.3V and A5 and 3.3V and it started working right away.

    Thanks a bunch for the help!

  10. #10
    Member
    Join Date
    Jun 2013
    Location
    Southern Colorado
    Posts
    66
    You're quite welcome......glad to hear about another successful T3.x project.

  11. #11
    If anyone's interested, here is my first test of my midi-keyboard-radio:
    http://instagram.com/p/utAFiBHFxI/

    the main thing to fix is I need to rig a better antenna!

Posting Permissions

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