Помогите запустить радио
- Войдите на сайт для отправки комментариев
Пт, 10/01/2014 - 13:28
Всем сдрасте! Помогите запустить радио на 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); } }
Что за радио на tea5767 ?
ФМ приёмник 88-108Мгц.
http://fabtolab.com/TEA5767-FM-module
А вот то что хочу повторить.
http://www.youtube.com/watch?v=mB5CpfNR3Mo
Какая у вас дуина? Куда подключены выводы 1 и 2 модуля к дуине?
У меня уна. Модуль подключён правильно. sda на А4,scl на А5.У меня проблема с энкодером. И кнопкой. Нет реакции. Изначально энкодер был подключён к 1 и 4.А кнопка на 0. Я переправил на 3 и 4. Кнопку на 6.
Sda на что 4 ? Scl на что 5 ? 4и5 должны быть ad4 и ad5 , у меня на нане не заработало, пока по схеме не разобрался, потому как в описании написано
да. я ошибся. А4и А5
Энкодер оставьте где есть, а кнопка должна быть на 2 цифровом выводе:
И обратите внимание на номера прерываний:
attachInterrupt()
Я запускал другой. Всё работало.
http://www.youtube.com/watch?v=NBE0KwzBocU
Мне понравился этот . Там энкодер вместо кнопарей.Энкодер проверил. Залил тестовый скетч.Все пашет. В теминале всё бегает.
maksim,Огромное человеческое спасибо! Всё заработало!Ещё вопрос. Как увеличить скорость опроса энкодера?А то если быстро крутить не успевает за ним.
Для этого прийдется посадить энкодер на оба прерывания, а кнопку использовать без прерывания, либо использовать PCINT прерывания. Оба варианта приведут к значительному переписыванию кода.
Ясно. Я не потену.
Ещё раз Спасибо!!
Попробую другой энкодер.С меньшим количеством шагов.
Ещё один глупый вопрос.
Как добавить ещё один знак после запятой я разобрался.
А как сделать шаг перестройки не 0.1 а 0.05?
Подскажите. lcd.write(183); // Japanese character that looks like an antenna :)
Есть таблица символов? А то методом тыка долго перебирать.
"Попробую другой энкодер.С меньшим количеством шагов."
Другой энкодер вас не спасет.
В коде, опрос энкодера организован через прерыание и после выполнение прерывания, вы получаете статус в какую сторону был повернут энкодер (биты 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
roman2712@,спасибо.
Вроде стал лучше бегать по частоте.
А вот как сделать шаг 0.05 я так и не понял.
frequency += 0.1 Эта строка отвечает за шаг?
да
frequency += 0.1 - вверх
frequency -= 0.1 - вниз
если надо частоту уменьшать на 0.05 то:
frequency += 0.05 - вверх
frequency -= 0.05 - вниз
Тогда если я правильно понимаю то lcd.print(frequency, 1);
Количество знаков после запятой. Правильно?
Похоже что да, я таким методом не выводил. Можно поиграться с цифрой после запятой. В http://arduino.cc/en/Reference/LiquidCrystalPrint нет информации об этом, но если это работает для чисел с запятой (frequency имеет тип Float), это круто :)
Не получается сделать шаг меньше.
Ставлю 0.05 В низ идет 0.1, а в стоит.
Видать где то глубоко зарыто. Я со своим оптическим энкодером
пролетаю нужную частоту.
что то мне подсказывает что это с отображением вопрос и копать надо здесь frequency = floor(Radio.frequency_available(buf) / 100000 + .5) / 10;. Похоже если написать frequency += 0.05 и frequency -= 0.05, перерстраиваться будет, но показывать этот шаг не будет.
Так я и пишу frequency += 0.05 и frequency -= 0.05.
Вниз по частоте идет -0.1 А в верх стоит.
Ещё вопрос. Есть другой проект. но там кнопки.
Сложно вместо кнопок вписать энкодер?
Не сложно, но надо код программы.
попробуй вот так:
frequency = 0.05 + frequency; в +
frequency = 0.05 - frequency; в -
Попробую. Вот код.
Глянь.
Энкодер подключить к 2 и 3 входу ардуино с подтяжкой через резистор 10к на 0. Желательно зашунтировав конденсатором 100 nF
Всё работает. только экран не успевает .
Если быстро крутить кракозябры выписывает.
Всем привет. наткнулся на эту тему, поэтому решил новую не создавать. Вообщем, в програмной части я еще совсем новичек, решил собрать это радио, все части есть, но возникла проблема, не компилируется скетч, вылезает куча ошибок, природа которых мне не очень ясна так как у всех все работает.
вот код
У Вас нету библиотеки TEA5767
Здравствуйте.
Гуру подскажите, что у меня за ошибка при компиляции?
берешь самую нижнию строку и кидаешь ее в гугл-перевод: Класс TEA5767 'не имеет члена с именем' set_frequency
"член" можно нежно на "метод" заменить.
За перевод конечно спасибо. :))
Но почему, судя по топику, у других работает, а у меня нет?
Простите за то что туплю, просто только осваиваю arduino.
P.S. И в библиотеке этот метод вроде есть.
P.P.S. Причём второй код (под дисплей 5110) компилируется без ошибок :((
За перевод конечно спасибо. :))
Но почему, судя по топику, у других работает, а у меня нет?
Простите за то что туплю, просто только осваиваю arduino.
P.S. И в библиотеке этот метод вроде есть.
P.P.S. Причём второй код (под дисплей 5110) компилируется без ошибок :((
Прежде чем о чём-то говорить, необходимо увидеть Ваш код и как радиомодуль подключён к ардуино(и какой модуль ардуино?). Потому-как у меня был один пример(скетч), который работал с ардуино-нано, но напрочь отказывался работать с ардуино про-мини, хоть и чипы одинаковые.
Спасибо что отозвались, но я уже решил проблему, нашёл другую библиотеку и всё скопилироалось.
Добрый день. Подскажите, есть ли возможность смотреть уровни каналов на выходе модуля?