Помогите запустить радио

vovan
Offline
Зарегистрирован: 10.01.2014

Всем сдрасте! Помогите запустить радио на tea5767.

Сам писать программы пока не умею. Нашёл в инете скетч.

Всё загрузилось, lcd работает, модуль тоже распознаётся.

Но на энкодер и кнопку не реагирует. Энкодер рабочий.

Проверено в другой программе.

Прошу помочь запустить.

Вот программа.







Connections:
-----------
- Encoder (with "pushable" shaft switch):
Push button     ---> Arduino pin 6
Encoder pin "A" ---> Arduino pin 3
Encoder pin "B" ---> Arduino pin 4


- LCD:
D7 ---> Arduino pin 8
D6 ---> Arduino pin 9
D5 ---> Arduino pin 10
D4 ---> Arduino pin 11
RS ---> Arduino pin 13
RW ---> GND
E ----> Arduino pin 12
VO ---> 2k2 resistor to GND (contrast)


- TEA5756 module:

Top view:
+-10--9--8--7--6-+
|  +------+  ++  |
|  | TEA  |  ||  |
|  | 5767 |  ||  |
|  +------+  ++  |
+--1--2--3--4--5-+

1 ----> Arduino SDA
2 ----> Arduino SCL
3 ----> GND
5 ----> +3.3V
6 ----> GND
7 ----> Audio out (right channel)
8 ----> Audio out (left channel)
10 ---> Antena

Thank you for your interest.
Have fun!
rodolfo.manin@gmail.com

*/


#include <LiquidCrystal.h>
#include <Wire.h>
#include <TEA5767.h>

// Encoder pins
#define ENCODER_SW 6
#define ENCODER_A  3
#define ENCODER_B  4

// Custom characters
#define SCALE_CLEAR   5    // Radio dial scale
#define STEREO_CHAR_S 6    // Stylized "S"
#define STEREO_CHAR_T 7    // Stylized "T"

// Global status flags
#define ST_AUTO    0      // Auto mode (toggled by the push button)
#define ST_STEREO  1      // Radio module detected a stereo pilot
#define ST_GO_UP   2      // Encoder being turned clockwise
#define ST_GO_DOWN 3      // Encoder being turned counterclockwise
#define ST_SEARCH  4      // Radio module is perfoming an automatic search

TEA5767 Radio;
float frequency = 88;
byte status = 0;

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

/*******************************************\
 *             updateScale()               *
 * Moves the "needle" over the radio scale *
\*******************************************/
void updateScale() {
  int lcdBase = (frequency  - 88) * 4;  // LCD column pixel index (0 <= lcdBase <= (16 * 5))
  if(lcdBase > 79) lcdBase = 79;
  
  int lcdMajor = lcdBase / 5;    // LCD character index (0 <= lcdMajor <= 15)
  int lcdMinor = lcdBase % 5;    // LCD pixel column index within the character (0 <= lcdMinor <= 4)
  
  if(lcdMajor > 0) {
    // The radio dial needle is not at the leftmost position:
    // clean the character on the left (to erase previous neddle position)
    lcd.setCursor(lcdMajor  - 1, 0);
    lcd.write(SCALE_CLEAR);
  } else
    lcd.setCursor(lcdMajor, 0);
  lcd.write(lcdMinor);
  
  if(lcdMajor < 15)
    // Not at rightmost position: clear the character on the right
    lcd.write(SCALE_CLEAR);
}


/******************************\
 *         isrEncoder()       *
 * Catch encoder´s interrupts *
\******************************/

void isrEncoder() {
  delay(50);    // Debouncing (for crappy encoders)
  if(digitalRead(ENCODER_B) == HIGH){
    bitWrite(status, ST_GO_UP, 1);
  } else
    bitWrite(status, ST_GO_DOWN, 1);
}


/*****************************\
 *        isrSwitch()        *
 * Catch switch´s interrupts *
\*****************************/
void isrSwitch() {
  delay(50);    // Debouncing
  if(bitRead(status, ST_AUTO))
    bitWrite(status, ST_AUTO, 0);
  else
    bitWrite(status, ST_AUTO, 1);
}


/*******************\
 * Arduino Setup() *
\*******************/
void setup() {
  int i;
  byte needleChar[8];

  // Stylized "S"
  byte stereoChar1[8] = {
    0b01111,
    0b11000,
    0b11011,
    0b11101,
    0b11110,
    0b11000,
    0b01111,
    0b00000
  };
  lcd.createChar(STEREO_CHAR_S, stereoChar1);

  // Stylized "T"
  byte stereoChar2[8] = {
    0b11110,
    0b00011,
    0b10111,
    0b10111,
    0b10111,
    0b10111,
    0b11110,
    0b00000
  };
  lcd.createChar(STEREO_CHAR_T, stereoChar2);

  // Dial scale background
  byte scaleChar[8] = {
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00100,
    0b10101,
    0b10101
  };
  lcd.createChar(SCALE_CLEAR, scaleChar);

  // Create custom character to represent all (5) possible needle´s position
  for(int j = 0; j < 5; j++) {
    for(i = 0; i < 8; i++)
      needleChar[i] = scaleChar[i] | (0b10000 >> j);
    lcd.createChar(j, needleChar);
  }

  lcd.begin(16, 2);
  lcd.clear();
  
  // Draw the dial scale´s background
  for(i = 0; i < 16; i++)
    lcd.write(SCALE_CLEAR);
   
  pinMode(ENCODER_SW, INPUT); digitalWrite(ENCODER_SW, HIGH);
  pinMode(ENCODER_A,INPUT);  digitalWrite(ENCODER_A, HIGH);
  pinMode(ENCODER_B, INPUT);  digitalWrite(ENCODER_B, HIGH);
  
  // Arduino Leonardo has interrupts 2 and 3 (for pins 0 and 1).
  // You can use the PinChangeInt to modify this code for other Arduinos
  // (pins 2 and 3 have interrupts on all Arduinos, but they are being used by the TEA5767´s I2C interface)
  attachInterrupt(2, isrSwitch, RISING);
  attachInterrupt(3, isrEncoder, RISING);

  // Initialize the radio module
  Wire.begin();
  Radio.init();
  Radio.set_frequency(frequency);
}


/******************\
 * Arduino Loop() *
\******************/
void loop() {
  unsigned char buf[5];
  int stereo;
  int signalLevel;
  int searchDirection;
  
  // Update the Auto / Manual indicator
  lcd.setCursor(12, 1);
  lcd.write(bitRead(status, ST_AUTO) ? 'A' : 'M');

  if (Radio.read_status(buf) == 1) {
    // Get radio data
    frequency = floor(Radio.frequency_available(buf) / 100000 + .5) / 10;
    stereo = Radio.stereo(buf);
    // 0 <= Radio.signal_level <= 15
    signalLevel = (Radio.signal_level(buf) * 100) / 15;

    // Update the radio dial
    updateScale();
    
    // Signal level indicator
    lcd.setCursor(0, 1);
    lcd.write(183);    // Japanese character that looks like an antenna :)
    if(signalLevel < 100) lcd.write(' ');
    lcd.print(signalLevel);
    lcd.write('%');

    // Frequency indicator
    lcd.setCursor(6, 1);
    if(frequency < 100) lcd.write(' ');
    lcd.print(frequency, 1);

    // Mono / stereo indicator
    lcd.setCursor(14, 1);
    if(stereo){
      lcd.write(STEREO_CHAR_S);
      lcd.write(STEREO_CHAR_T);
    } else
      lcd.print("  ");
  }
  
  if(bitRead(status, ST_SEARCH)) {   // Is the radio performing an automatic search?
    if(Radio.process_search(buf, searchDirection) == 1) {
      bitWrite(status, ST_SEARCH, 0);
    }
  }

  // Encoder being turned clockwise (+)
  if(bitRead(status, ST_GO_UP)) {
    if(bitRead(status, ST_AUTO) && !bitRead(status, ST_SEARCH)) {
      // Automatic search mode (only processed if the radio is not currently performing a search)
      bitWrite(status, ST_SEARCH, 1);
      searchDirection = TEA5767_SEARCH_DIR_UP;
      Radio.search_up(buf);
      delay(50);
    } else {
      // Manual tuning mode
      if(frequency < 108) {
        frequency += 0.1;
        Radio.set_frequency(frequency);
      }
    }
    bitWrite(status, ST_GO_UP, 0);
  }

  // Encoder being turned counterclockwise (-)
  if(bitRead(status, ST_GO_DOWN)) {
    if(bitRead(status, ST_AUTO) && !bitRead(status, ST_SEARCH)) {
      // Automatic search mode (only processed if the radio is not currently performing a search)
      bitWrite(status, ST_SEARCH, 1);
      searchDirection = TEA5767_SEARCH_DIR_DOWN;
      Radio.search_down(buf);
      delay(50);
    } else {
      // Manual tuning mode
      if(frequency > 88) {
        frequency -= 0.1;
        Radio.set_frequency(frequency);
      }
    }
    bitWrite(status, ST_GO_DOWN, 0);
  }
      
}

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Что за радио на tea5767 ?

vovan
Offline
Зарегистрирован: 10.01.2014

ФМ приёмник 88-108Мгц.

http://fabtolab.com/TEA5767-FM-module 

А вот то что хочу повторить.

http://www.youtube.com/watch?v=mB5CpfNR3Mo

maksim
Offline
Зарегистрирован: 12.02.2012

Какая у вас дуина? Куда подключены выводы 1 и 2 модуля к дуине? 

vovan
Offline
Зарегистрирован: 10.01.2014

У меня уна. Модуль подключён правильно. sda на А4,scl на А5.У меня проблема с энкодером. И кнопкой. Нет реакции. Изначально энкодер был подключён к 1 и 4.А кнопка на 0. Я переправил на 3 и 4. Кнопку на 6.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Sda на что 4 ? Scl на что 5 ? 4и5 должны быть ad4 и ad5 , у меня на нане не заработало, пока по схеме не разобрался, потому как в описании написано 

I2C: 4 (SDA) and 5 (SCL). Support I2C (TWI) communication using the Wire library (documentation on the Wiring website).
 
vovan
Offline
Зарегистрирован: 10.01.2014

да. я ошибся. А4и А5

inspiritus
Offline
Зарегистрирован: 17.12.2012
Прежде, чем запускать в общем навороченное устройство из трех модулей : радио, энкодер, дисплей, и без опыта , попробуйте разобраться с каждым в отдельности. Например для радио есть экзампл , позволяющий просто проверить работоспособность на фиксированной частоте. 
maksim
Offline
Зарегистрирован: 12.02.2012

Энкодер оставьте где есть, а кнопка должна быть на 2 цифровом выводе:

#define ENCODER_SW 2

И обратите внимание на номера прерываний:

  attachInterrupt(0, isrSwitch, RISING);
  attachInterrupt(1, isrEncoder, RISING);

attachInterrupt()

 

vovan
Offline
Зарегистрирован: 10.01.2014

Я запускал другой. Всё работало.

http://www.youtube.com/watch?v=NBE0KwzBocU 

Мне понравился этот . Там энкодер вместо кнопарей.Энкодер проверил. Залил тестовый скетч.Все пашет. В теминале всё бегает. 

vovan
Offline
Зарегистрирован: 10.01.2014

maksim,Огромное человеческое спасибо! Всё заработало!Ещё вопрос. Как увеличить скорость опроса энкодера?А то если быстро крутить не успевает за ним.

maksim
Offline
Зарегистрирован: 12.02.2012

Для этого прийдется посадить энкодер на оба прерывания, а кнопку использовать без прерывания, либо использовать PCINT прерывания. Оба варианта приведут к значительному переписыванию кода.

vovan
Offline
Зарегистрирован: 10.01.2014

Ясно. Я не потену. 

Ещё раз Спасибо!!

Попробую другой энкодер.С меньшим количеством шагов.

vovan
Offline
Зарегистрирован: 10.01.2014

Ещё один глупый вопрос.

Как добавить ещё один знак после запятой я разобрался.

А как сделать шаг перестройки не 0.1 а 0.05?

vovan
Offline
Зарегистрирован: 10.01.2014

Подскажите. lcd.write(183); // Japanese character that looks like an antenna :)

Есть таблица символов? А то методом тыка долго перебирать.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

"Попробую другой энкодер.С меньшим количеством шагов."

Другой энкодер вас не спасет. 

В коде, опрос энкодера организован через прерыание и после выполнение прерывания, вы получаете статус в какую сторону был повернут энкодер (биты ST_GO_UP и ST_GO_DOWN). Увеличение или уменьшение частоты на шаг поиска в ручном режиме идет в строках коде с 253 строки и с 271 строки по этим битам. Соответсвенно, возможно следующая ситуация:

1) Повернули энкодер в + на 1 шаг

2)  ST_GO_UP стало равно 1 

3) в случае ручного поиска frequency += 0.1 

4) Обнулили бит ST_GO_UP

Но если, до выполнения п.3, повернуть ручку энкодера еще раз в + на 1 или более шагов (быстрое вращение энкодера), то эти данные о вращении пропадут. Так как каждый раз при повороте  ST_GO_UP будет устанавливаться в 1 прерыванием, а он до п.3, и так уже в 1.

Дополнительно, в прерывании сидит функция delay(50) (уменьшение дребезга), что не корректно, так как пока эта функция не будет завершена, из прерывания микроконтроллер не выйдет и получается что при быстром вращении мы из прерывания просто не успеваем выйти, что бы обработать новый шаг.

По правильному, при ручном поиске следовало бы увеличивать значение frequency по прерыванию, при ручном режиме поиска. А так же убрать задержку, (или хотябы уменьшить задержку до 10). Для уменьшения дребезга, на выходы энкодера повесить конденсаторы по 100nF.

Таблицу символов можно посмотреть в http://www.datasheet4u.com/datasheet/L/C/D/LCD-1602A_CA.pdf.html

183 => 1011 0111 => UpperBit 1011 LowerBit  0111

 

 

 

vovan
Offline
Зарегистрирован: 10.01.2014

roman2712@,спасибо.

Вроде стал лучше бегать по частоте.

А вот как сделать шаг 0.05 я так и не понял.

frequency += 0.1 Эта строка отвечает за шаг?

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

да 

frequency += 0.1 - вверх 

frequency -= 0.1 - вниз

если надо частоту уменьшать на 0.05 то:

frequency += 0.05 - вверх 

frequency -= 0.05 - вниз

 

vovan
Offline
Зарегистрирован: 10.01.2014

Тогда если я правильно понимаю то lcd.print(frequency, 1);

Количество знаков после запятой. Правильно?

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Похоже что да, я таким методом не выводил. Можно поиграться с цифрой после запятой. В http://arduino.cc/en/Reference/LiquidCrystalPrint нет информации об этом, но если это работает для чисел с запятой (frequency имеет тип Float), это круто :)

vovan
Offline
Зарегистрирован: 10.01.2014

Не получается сделать шаг меньше.

Ставлю 0.05 В низ идет 0.1, а в стоит.

Видать где то глубоко зарыто. Я со своим оптическим энкодером

пролетаю нужную частоту.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

что то мне подсказывает что это с отображением вопрос и копать надо здесь frequency = floor(Radio.frequency_available(buf) / 100000 + .5) / 10;. Похоже если написать frequency += 0.05 и frequency -= 0.05, перерстраиваться будет, но показывать этот шаг не будет.

vovan
Offline
Зарегистрирован: 10.01.2014

Так я и пишу frequency += 0.05 и frequency -= 0.05.

Вниз по частоте идет -0.1 А в верх стоит.

Ещё вопрос. Есть другой проект. но там кнопки.

Сложно вместо кнопок вписать энкодер?

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Не сложно, но надо код программы. 

попробуй вот так:

 frequency = 0.05 + frequency; в +

 frequency = 0.05 - frequency; в -

 

vovan
Offline
Зарегистрирован: 10.01.2014

Попробую. Вот код.

Глянь.

// TEA5767 und Nokia 5110 LCD Display

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// D7 - Serial clock out (CLK oder SCLK)
// D6 - Serial data out (DIN)
// D5 - Data/Command select (DC oder D/C)
// D4 - LCD chip select (CE oder CS)
// D3 - LCD reset (RST)
Adafruit_PCD8544 lcd = Adafruit_PCD8544(7, 6, 5, 4, 3);

#include <Wire.h>

#define button_frequency_up     13
#define button_frequency_down   12
#define button_mute             11

#define TEA5767_mute_left_right  0x06
#define TEA5767_MUTE_FULL        0x80
#define TEA5767_ADC_LEVEL_MASK   0xF0
#define TEA5767_STEREO_MASK      0x80


int old_frequency=-1;
int frequency=10260;

byte old_stereo=0;
byte stereo=1;

byte old_mute=1;
byte mute=0;

byte old_signal_level=1;
byte signal_level=0;

unsigned long last_pressed;

void setup(void) {
  
  pinMode(button_frequency_up, INPUT);
  pinMode(button_frequency_down, INPUT);
  pinMode(button_mute, INPUT);
  
  Wire.begin();
  
  TEA5767_set_frequency();

  lcd.begin();
  lcd.setContrast(60);
  lcd.clearDisplay();
   
  set_text(1,2,"FM Radio",BLACK,1);  
  //set_text(14,147,"blog.simtronyx.de",BLACK,1);
  
}


void loop() {

    if(frequency!=old_frequency){
      set_text(old_frequency>=10000?6:14,17,value_to_string(old_frequency),WHITE,2);
      set_text(frequency>=10000?6:14,17,value_to_string(frequency),BLACK,2);
      old_frequency=frequency;
    }
    
    TEA5767_read_data();
      
    if(old_stereo!=stereo){ 
        set_text(old_stereo?22:28,39,old_stereo?"Stereo":"Mono",WHITE,1);
        set_text(stereo?22:28,39,stereo?"Stereo":"Mono",BLACK,1);
        old_stereo=stereo;
    }
    
    if(old_signal_level!=signal_level){
        set_text(old_signal_level<10?76:70,39,String((int)old_signal_level),WHITE,1);
        set_text(signal_level<10?76:70,39,String((int)signal_level),BLACK,1);
        old_signal_level=signal_level;
        show_signal_level(signal_level);
    }
    
    if(old_mute!=mute){
        set_text(1,39,old_mute?"M":"S",WHITE,1);
        set_text(1,39,mute?"M":"S",BLACK,1);
        old_mute=mute;
    }
      
    delay(50);
    
  
  if(digitalRead(button_frequency_down)==HIGH){
    
    frequency=frequency-5;
    if(frequency<8750)frequency=10800;
    TEA5767_set_frequency();
  }
  if(digitalRead(button_frequency_up)==HIGH){
    
    frequency=frequency+5;
    if(frequency>10800)frequency=8750;
    TEA5767_set_frequency();
  }

  if(digitalRead(button_mute)==HIGH){
    
    TEA5767_mute();
  }
  
  delay(50);
  
}

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

unsigned int frequencyB;

unsigned char TEA5767_buffer[5]={0x00,0x00,0xB0,0x10,0x00};

void TEA5767_write_data(byte data_size){
   
  delay(50);
  
  Wire.beginTransmission(0x60);
  
  for(byte i=0;i<data_size;i++)
    Wire.write(TEA5767_buffer[i]);
  
  Wire.endTransmission();
  
  delay(50);
}

void TEA5767_mute(){ 
  
  if(!mute){   
    mute = 1;   
    TEA5767_buffer[0] |= TEA5767_MUTE_FULL;
    TEA5767_write_data(2);
//    TEA5767_buffer[0] &= ~TEA5767_mute;
//    TEA5767_buffer[2] |= TEA5767_mute_left_right;
  }   
  else{
    mute = 0;   
    TEA5767_buffer[0] &= ~TEA5767_MUTE_FULL;
    TEA5767_write_data(2);
//    TEA5767_buffer[0] |= TEA5767_mute;
//    TEA5767_buffer[2] &= ~TEA5767_mute_left_right;
  }
    
//  TEA5767_write_data(3);
}

void TEA5767_set_frequency()
{
  frequencyB = 4 * (frequency * 10000 + 225000) / 32768;
  TEA5767_buffer[0] = frequencyB >> 8;
  if(mute)TEA5767_buffer[0] |= TEA5767_MUTE_FULL;
  TEA5767_buffer[1] = frequencyB & 0XFF;
  
  TEA5767_write_data(5);
}

int TEA5767_read_data() {
  
  unsigned char buf[5];
  memset (buf, 0, 5);
  
  Wire.requestFrom (0x60, 5); 

  if (Wire.available ()) {
    for (int i = 0; i < 5; i++) {
      buf[i] = Wire.read ();
    }
        
    stereo = (buf[2] & TEA5767_STEREO_MASK)?1:0;
    signal_level = ((buf[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
    
    return 1;
  } 
  else return 0;
}

void show_signal_level(int level){
  
  byte xs=68;
  byte ys=8;
  for(int i=0;i<15;i++){
    if(i%2!=0)lcd.drawLine(xs+i,ys,xs+i,ys-i/2,level>=i?BLACK:WHITE);
  }
}

void set_text(int x,int y,String text,int color,int textsize){
  
  lcd.setTextSize(textsize);
  lcd.setTextColor(color); 
  lcd.setCursor(x,y);     
  lcd.println(text);      
  lcd.display();         
}


String value_to_string(int value){
  
  String value_string = String(value / 100);
  value_string = value_string + '.' + ((value%100<10)?"0":"") + (value % 100);
  return value_string;
}

 

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014
прописываем переменные:
 
int enc_pin_A = 2; /этот обязательно
int enc_pin_B = 3; /или любой другой
 
в void setup ()
attachInterrupt(1, encoder, RISING);
 
и сама обработка прерывания
 
void encoder() {
  if(digitalRead(enc_pin_B)) ++frequency;
  else --frequency;
}

Энкодер подключить к 2 и 3 входу ардуино с подтяжкой через резистор 10к на 0. Желательно зашунтировав конденсатором 100 nF

 

vovan
Offline
Зарегистрирован: 10.01.2014

Всё работает. только экран не успевает .

Если быстро крутить кракозябры выписывает.

Alewko
Offline
Зарегистрирован: 03.06.2015

Всем привет. наткнулся на эту тему, поэтому решил новую не создавать. Вообщем, в програмной части я еще совсем новичек, решил собрать это радио, все части есть, но возникла проблема, не компилируется скетч, вылезает куча ошибок, природа которых мне не очень ясна так как у всех все работает.

 

вот код

 

/*
Simple radio tuner using Arduino Leonardo and the Philips TEA5767 module (Arduino Uno version)
Notes:
-----
- The TEA5767 maximum supply voltage is 5V.  Be sure your Arduino is not sourcing more than 5V
- The TEA5767 does not update the signal level indicator on read.  The signal level will only be update on station change
- If you get some glitches on the encoder or on the pushbutton, use a snubber network, like this:
Arduino pin >----+----/\/\/\/---------> Encoder or switch pin
                 |     100Ohms resistor
               -----
               ----- 47nF cap
                 |
                ---
                GND
Connections:
-----------
- Encoder (with "pushable" shaft switch):
Push button     ---> Arduino pin 2
Encoder pin "A" ---> Arduino pin 3
Encoder pin "B" ---> Arduino pin 4
- LCD:
D7 ---> Arduino pin 8
D6 ---> Arduino pin 9
D5 ---> Arduino pin 10
D4 ---> Arduino pin 11
RS ---> Arduino pin 13
RW ---> GND
E ----> Arduino pin 12
VO ---> 2k2 resistor to GND (contrast)
- TEA5756 module:
Top view:
+-10--9--8--7--6-+
|  +------+  ++  |
|  | TEA  |  ||  |
|  | 5767 |  ||  |
|  +------+  ++  |
+--1--2--3--4--5-+
1 ----> Arduino SDA
2 ----> Arduino SCL
3 ----> GND
5 ----> +5V
6 ----> GND
7 ----> Audio out (right channel)
8 ----> Audio out (left channel)
10 ---> Antenna
Thank you for your interest.
Have fun!
rodolfo.manin@gmail.com
*/
 
 
#include <LiquidCrystal.h>
#include <Wire.h>
 
// Get TEA5767 library at https://github.com/andykarpov/TEA5767
#include <TEA5767.h>
 
// Encoder pins
#define ENCODER_SW 2
#define ENCODER_A  3
#define ENCODER_B  4
 
// Custom characters
#define SCALE_CLEAR   5    // Radio dial scale
#define STEREO_CHAR_S 6    // Stylized "S"
#define STEREO_CHAR_T 7    // Stylized "T"
 
// Global status flags
#define ST_AUTO    0      // Auto mode (toggled by the push button)
#define ST_STEREO  1      // Radio module detected a stereo pilot
#define ST_GO_UP   2      // Encoder being turned clockwise
#define ST_GO_DOWN 3      // Encoder being turned counterclockwise
#define ST_SEARCH  4      // Radio module is perfoming an automatic search
 
TEA5767 Radio;
float frequency = 88;
byte status = 0;
 
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
 
/*******************************************\
 *             updateScale()               *
 * Moves the "needle" over the radio scale *
\*******************************************/
void updateScale() {
  int lcdBase = (frequency  - 88) * 4;  // LCD column pixel index (0 <= lcdBase <= (16 * 5))
  if(lcdBase > 79) lcdBase = 79;
  
  int lcdMajor = lcdBase / 5;    // LCD character index (0 <= lcdMajor <= 15)
  int lcdMinor = lcdBase % 5;    // LCD pixel column index within the character (0 <= lcdMinor <= 4)
  
  if(lcdMajor > 0) {
    // The radio dial needle is not at the leftmost position:
    // clean the character on the left (to erase previous neddle position)
    lcd.setCursor(lcdMajor  - 1, 0);
    lcd.write(SCALE_CLEAR);
  } else
    lcd.setCursor(lcdMajor, 0);
  lcd.write(lcdMinor);
  
  if(lcdMajor < 15)
    // Not at rightmost position: clear the character on the right
    lcd.write(SCALE_CLEAR);
}
 
 
/******************************\
 *         isrEncoder()       *
 * Catch encoder´s interrupts *
\******************************/
void isrEncoder() {
  delay(50);    // Debouncing (for crappy encoders)
  if(digitalRead(ENCODER_B) == HIGH){
    bitWrite(status, ST_GO_UP, 1);
  } else
    bitWrite(status, ST_GO_DOWN, 1);
}
 
 
/*****************************\
 *        isrSwitch()        *
 * Catch switch´s interrupts *
\*****************************/
void isrSwitch() {
  delay(50);    // Debouncing
  if(bitRead(status, ST_AUTO))
    bitWrite(status, ST_AUTO, 0);
  else
    bitWrite(status, ST_AUTO, 1);
}
 
 
/*******************\
 * Arduino Setup() *
\*******************/
void setup() {
  int i;
  byte needleChar[8];
 
  // Stylized "S"
  byte stereoChar1[8] = {
    0b01111,
    0b11000,
    0b11011,
    0b11101,
    0b11110,
    0b11000,
    0b01111,
    0b00000
  };
  lcd.createChar(STEREO_CHAR_S, stereoChar1);
 
  // Stylized "T"
  byte stereoChar2[8] = {
    0b11110,
    0b00011,
    0b10111,
    0b10111,
    0b10111,
    0b10111,
    0b11110,
    0b00000
  };
  lcd.createChar(STEREO_CHAR_T, stereoChar2);
 
  // Dial scale background
  byte scaleChar[8] = {
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00100,
    0b10101,
    0b10101
  };
  lcd.createChar(SCALE_CLEAR, scaleChar);
 
  // Create custom character to represent all (5) possible needle´s position
  for(int j = 0; j < 5; j++) {
    for(i = 0; i < 8; i++)
      needleChar[i] = scaleChar[i] | (0b10000 >> j);
    lcd.createChar(j, needleChar);
  }
 
  lcd.begin(16, 2);
  lcd.clear();
  
  // Draw the dial scale´s background
  for(i = 0; i < 16; i++)
    lcd.write(SCALE_CLEAR);
   
  pinMode(ENCODER_SW, INPUT); digitalWrite(ENCODER_SW, HIGH);
  pinMode(ENCODER_A, INPUT);  digitalWrite(ENCODER_A, HIGH);
  pinMode(ENCODER_B, INPUT);  digitalWrite(ENCODER_B, HIGH);
  
  attachInterrupt(0, isrSwitch, RISING);
  attachInterrupt(1, isrEncoder, RISING);
 
  // Initialize the radio module
  Wire.begin();
  Radio.init();
  Radio.set_frequency(frequency);
}
 
 
/******************\
 * Arduino Loop() *
\******************/
void loop() {
  unsigned char buf[5];
  int stereo;
  int signalLevel;
  int searchDirection;
  
  // Update the Auto / Manual indicator
  lcd.setCursor(12, 1);
  lcd.write(bitRead(status, ST_AUTO) ? 'A' : 'M');
 
  if (Radio.read_status(buf) == 1) {
    // Get radio data
    frequency = floor(Radio.frequency_available(buf) / 100000 + .5) / 10;
    stereo = Radio.stereo(buf);
    // 0 <= Radio.signal_level <= 15
    signalLevel = (Radio.signal_level(buf) * 100) / 15;
 
    // Update the radio dial
    updateScale();
    
    // Signal level indicator
    lcd.setCursor(0, 1);
    lcd.write(183);    // Japanese character that looks like an antenna :)
    if(signalLevel < 100) lcd.write(' ');
    lcd.print(signalLevel);
    lcd.write('%');
 
    // Frequency indicator
    lcd.setCursor(6, 1);
    if(frequency < 100) lcd.write(' ');
    lcd.print(frequency, 1);
 
    // Mono / stereo indicator
    lcd.setCursor(14, 1);
    if(stereo){
      lcd.write(STEREO_CHAR_S);
      lcd.write(STEREO_CHAR_T);
    } else
      lcd.print("  ");
  }
  
  if(bitRead(status, ST_SEARCH)) {   // Is the radio performing an automatic search?
    if(Radio.process_search(buf, searchDirection) == 1) {
      bitWrite(status, ST_SEARCH, 0);
    }
  }
 
  // Encoder being turned clockwise (+)
  if(bitRead(status, ST_GO_UP)) {
    if(bitRead(status, ST_AUTO) && !bitRead(status, ST_SEARCH)) {
      // Automatic search mode (only processed if the radio is not currently performing a search)
      bitWrite(status, ST_SEARCH, 1);
      searchDirection = TEA5767_SEARCH_DIR_UP;
      Radio.search_up(buf);
      delay(50);
    } else {
      // Manual tuning mode
      if(frequency < 108) {
        frequency += 0.1;
        Radio.set_frequency(frequency);
      }
    }
    bitWrite(status, ST_GO_UP, 0);
  }
 
  // Encoder being turned counterclockwise (-)
  if(bitRead(status, ST_GO_DOWN)) {
    if(bitRead(status, ST_AUTO) && !bitRead(status, ST_SEARCH)) {
      // Automatic search mode (only processed if the radio is not currently performing a search)
      bitWrite(status, ST_SEARCH, 1);
      searchDirection = TEA5767_SEARCH_DIR_DOWN;
      Radio.search_down(buf);
      delay(50);
    } else {
      // Manual tuning mode
      if(frequency > 88) {
        frequency -= 0.1;
        Radio.set_frequency(frequency);
      }
    }
    bitWrite(status, ST_GO_DOWN, 0);
  }
 
}
 
 
а вот ошибки
 
sketch_jun03f:76: error: 'TEA5767' does not name a type
sketch_jun03f.ino: In function 'void setup()':
sketch_jun03f:203: error: 'Radio' was not declared in this scope
sketch_jun03f.ino: In function 'void loop()':
sketch_jun03f:221: error: 'Radio' was not declared in this scope
sketch_jun03f:253: error: 'Radio' was not declared in this scope
sketch_jun03f:263: error: 'TEA5767_SEARCH_DIR_UP' was not declared in this scope
sketch_jun03f:264: error: 'Radio' was not declared in this scope
sketch_jun03f:270: error: 'Radio' was not declared in this scope
sketch_jun03f:281: error: 'TEA5767_SEARCH_DIR_DOWN' was not declared in this scope
sketch_jun03f:282: error: 'Radio' was not declared in this scope
sketch_jun03f:288: error: 'Radio' was not declared in this scope
 
 
если кто нибудь поможет решить это или хотябы подскажет, буду искренне благодарен;)

 

sandr4
sandr4 аватар
Offline
Зарегистрирован: 11.02.2015

 У Вас нету библиотеки    TEA5767

DeVit
Offline
Зарегистрирован: 07.06.2016

Здравствуйте.

Гуру подскажите, что у меня за ошибка при компиляции?

Radio_TEA5767:278: error: 'class TEA5767' has no member named 'set_frequency'
 
         Radio.set_frequency(frequency);
 
               ^
 
exit status 1
'class TEA5767' has no member named 'set_frequency'
lean_74
Offline
Зарегистрирован: 22.12.2015

берешь самую нижнию строку и кидаешь ее в гугл-перевод: Класс TEA5767 'не имеет члена с именем' set_frequency

"член" можно нежно на "метод" заменить.

DeVit
Offline
Зарегистрирован: 07.06.2016

За перевод конечно спасибо. :))

Но почему, судя по топику, у других работает, а у меня нет?

Простите за то что туплю, просто только осваиваю arduino.

P.S. И в библиотеке этот метод вроде есть.

P.P.S. Причём второй код (под дисплей 5110) компилируется без ошибок :((

sandr4
sandr4 аватар
Offline
Зарегистрирован: 11.02.2015

DeVit пишет:

За перевод конечно спасибо. :))

Но почему, судя по топику, у других работает, а у меня нет?

Простите за то что туплю, просто только осваиваю arduino.

P.S. И в библиотеке этот метод вроде есть.

P.P.S. Причём второй код (под дисплей 5110) компилируется без ошибок :((

Прежде чем о чём-то говорить, необходимо увидеть Ваш код и как радиомодуль подключён к ардуино(и какой модуль ардуино?). Потому-как у меня был один пример(скетч), который работал с ардуино-нано, но напрочь отказывался работать с ардуино про-мини, хоть и чипы одинаковые.

DeVit
Offline
Зарегистрирован: 07.06.2016

Спасибо что отозвались, но я уже решил проблему, нашёл другую библиотеку и всё скопилироалось.

Erinaceus
Offline
Зарегистрирован: 21.12.2018

Добрый день. Подскажите, есть ли возможность смотреть уровни каналов на выходе модуля?