Азбука Ардуино

Модератор: Gnat

Аватара пользователя
Pionka
Сообщения: 575
Зарегистрирован: Чт июн 08, 2017 9:18 pm
Откуда: Рязань

Азбука Ардуино

Сообщение Pionka » Пт май 15, 2020 11:27 pm

Можно разместить файл , например на Яндексдиске , а сюда , в сообщение, добавить ссылку на него. И его можно будет скачать по ссылке всем желающим.
Пример 3эпу-48 https://yadi.sk/i/U0v_gpdeQ6ebEQ
С уважением, Андрей Александрович.
Не делаю из лампы культа - просто слушаю на ней музыку :)

Аватара пользователя
Radiomann
Сообщения: 8043
Зарегистрирован: Чт мар 03, 2011 11:02 pm

Азбука Ардуино

Сообщение Radiomann » Пт май 15, 2020 11:36 pm

Pionka писал(а):
Пт май 15, 2020 11:27 pm
Можно разместить файл , например на Яндексдиске , а сюда , в сообщение, добавить ссылку на него.
Отличная идея!
Кутник Фёдор Фридрихович.
Ищу заднюю крышку VEF-Spidola или Spidola. Можно корпус-донор.

https://www.youtube.com/watch?v=65jaKGOuNs0
https://www.youtube.com/watch?v=ovkn_8sFfes

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Пт май 15, 2020 11:59 pm

Добавил к схеме pdf-ку. Спасибо. Завтра УВЧ рисовать начну.
erased

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Сб май 16, 2020 11:35 am

УВЧ. Играет роль преселектора. Ну и защита от статики. Если статика есть :)
Изображение
http://www.gesigor.ru/pdf/uvch.pdf
erased

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Вс май 17, 2020 4:18 pm

Теперь блок питания и вспомогательные цепи.
Изображение
http://www.gesigor.ru/pdf/BP.pdf
УНЧ собран по типовой схеме взятой отсюда: http://www.radiolamp.ru/shem/unch/4.php?no=53.
Потенциометр и элементы R1,R2,C1,C2 не используются. В качестве входного конденсатора 2.2 мкф неполярный.
erased

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Вс май 17, 2020 5:19 pm

Теперь небольшое описание:
За основу был взят код из библиотеки модуля RDA5807M. Затем был добавлены функции из программы часов на ИН-12. Это непосредсвенно вывод на индикаторы - show() и функция перебора цифр для антитравления катодов ламп scroll(). Моя программа еще не полностью рабочая. Я еще новичок в ардуине. Пытаюсь сделать так, чтоб приемник мог запоминать последнюю станцию по нажатию кнопки. Кнопка есть в валкодере. Библиотека Bounce2 для подавления дребезга контактов. При проектировании на ардуине, если есть комутируемые цепи, обязательно нужно бороться с дребезгом. Можно программно, как в данном случае.
В коде есть возможность отладки через терминал. В итоге, когда программа будет готова, это можно удалить.
Как я написал ранее, все это задумывалось в замен веньерного устройства. Я правда в бытовых приемниках не видел ИН-12 или похожих. У военных, в возбудителях видел.

УВЧ играет роль преселектора. У меня дома очень тяжелый прием. Телек вообще не ловит. Дом в тени плюс первый этаж. Ну и помех от имульных устройсв выше крыши. Бывает даже зарядка от телефона затыкает приемники, которые без входных контуров.

Программа ардуино высчитывает примерное напряжение на варикапы исходя из частоты. Сопряжение не идеально. Но так как запас усиления есть, то ошибка не страшна.
С выхода ардуино так же получаем сигнал уровня RSSI, который подаем на 6Е1П. Этот сигнал - ШИМ. RC цепочкой преобразовываем в нужный. Оптронами делаем гальваническую развязку.

Мои косяки: Неверно расчитан общий потребляемый ток. Вернее расчитан без запаса. Дроссель Д-23 слабоват. Но сейчас не все компаненты можно найти. То нужного ТАНа нет, то дросселя. Короче собирал из того что было. И на последней схеме разъем J2 должен быть перевернут.

Код: Выделить всё

#include <Wire.h>
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>

//Add the RDA5807M Library to the sketch.
#include <RDA5807M.h>
#include "CyberLib.h"
#include <Bounce2.h>
#define PIN_BUTTON 11

//Create an instance of the RDA5807M named radio
RDA5807M radio;

char command;
word status, frequency;
Encoder myEnc(2, 3);

int out1 = A3;
int out2 = A2;
int out4 = A1;
int out8 = A0;

int key1 = 4;
int key2 = 13;
int key3 = 7;
int key4 = 8;
int key5 = 12;

Bounce debouncer = Bounce();

long Frequency;
uint16_t Frequency_read = 0;                 // уставка частоты из eeprom
byte flag = 0;

void setup()
{
  // Создание соединения для отладки
  Serial.begin(9600);

  //Initialize the radio to the West-FM band. (see RDA5807M_BAND_* constants).
  //The mode will set the proper receiver bandwidth.
  radio.begin(RDA5807M_BAND_WORLD);
  // Инициализация модуля

  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);

  pinMode(out1,OUTPUT);
  pinMode(out2,OUTPUT);
  pinMode(out4,OUTPUT);
  pinMode(out8,OUTPUT);
 
  pinMode(key1,OUTPUT);
  pinMode(key2,OUTPUT);
  pinMode(key3,OUTPUT);
  pinMode(key4,OUTPUT);
  pinMode(key5,OUTPUT);
  scroll(25);
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  debouncer.attach(PIN_BUTTON);
  debouncer.interval(500);
}

long oldPosition  = -999;
long downPosition  = 8750;
long Position = 0;
long newPosition;

void loop()
{
    uint16_t Frequency_read=ReadEEPROM_Word(0);          // чтение из eeprom значение уставки
    int digits[4];
    debouncer.update();

//    if (downPosition != Frequency_read) {downPosition = Frequency_read;}

    Position = (myEnc.read()/4)*10;
    if (Position != 0) {
      newPosition = Position;

      }

    if (newPosition > 2050) {newPosition = 2050;}
    if (newPosition < 0) {newPosition = 0;}

    if (newPosition != oldPosition) {
       Frequency = newPosition + downPosition;
       oldPosition = newPosition;

      if (flag ==0 && Frequency != Frequency_read) {
        Frequency = Frequency_read;
        flag = 1;
        Serial.println("----read-----");
        oldPosition = Frequency - downPosition;
        newPosition = oldPosition;
      }

      Serial.println(Frequency);  // вывод в терминал значения переменных для отладки
      radio.setFrequency(Frequency);
      Serial.println(Frequency_read);
      Serial.println(oldPosition);
      Serial.println(newPosition);
      Serial.println(downPosition);
      Serial.println("---------------");

    }

    if (debouncer.fell())
       { //если кнопка нажата
          WriteEEPROM_Word(0, Frequency);        // запись в eeprom значение частоты
          Serial.println("!!!!!!!!!!!!!");

       }

    digits[0] = Frequency/10000;
    unsigned int temp1 = digits[0]*10000;
    digits[1] = (Frequency-temp1)/1000;
    temp1 += digits[1]*1000;
    digits[2] = (Frequency-temp1)/100;
    temp1 += digits[2]*100;
    digits[3] = (Frequency-temp1)/10;
    temp1 += digits[3]*10;
    digits[4] = Frequency-temp1;
    show(digits);
    analogWrite(10, 255-(round(radio.getRSSI()*255/127))); //сигнал уровня на 6Е1П
    analogWrite(9, 255-(round(Frequency*0.0390-313.25)));  //напряжение для варикапов УВЧ

  if(Serial.available()){
    //Decide what to do based on the character received.
    command = Serial.read();
    
    switch(command){
      case 'v':
        if(radio.volumeDown()) Serial.println(F("Volume decreased"));
        else Serial.println(F("ERROR: already at minimum volume"));
        Serial.flush();
        break;
      case 'V':
        if(radio.volumeUp()) Serial.println(F("Volume increased"));
        else Serial.println(F("ERROR: already at maximum volume"));
        Serial.flush();
        break;
      case 's':
        Serial.println(F("Seeking down with band wrap-around"));
        Serial.flush();
        radio.seekDown();
        break;
      case 'S':
        Serial.println(F("Seeking up with band wrap-around"));
        Serial.flush();
        radio.seekUp();
        break;
      case 'm':
        radio.mute();
        Serial.println(F("Audio muted"));
        Serial.flush();
        break;
      case 'M':
        radio.unMute();
        Serial.println(F("Audio unmuted"));
        Serial.flush();
        break;
      case 'f':
        frequency = radio.getFrequency();
        Serial.print(F("Currently tuned to "));
        Serial.print(frequency / 100);
        Serial.print(".");
        Serial.print(frequency % 100);
        Serial.println(F("MHz FM"));
        Serial.flush();
        break;
      case 'q': 
        Serial.print(F("RSSI = "));
        Serial.print(radio.getRSSI());
        Serial.println("=");
        Serial.print(255-(round(radio.getRSSI()*255/63)));
        Serial.println("dBuV");
        Serial.flush();
        break;
      case 't':
        status = radio.getRegister(RDA5807M_REG_STATUS);
        Serial.println(F("Status register {"));
        if(status & RDA5807M_STATUS_RDSR)
            Serial.println(F("* RDS Group Ready"));
        if(status & RDA5807M_STATUS_STC)
            Serial.println(F("* Seek/Tune Complete"));
        if(status & RDA5807M_STATUS_SF)
            Serial.println(F("* Seek Failed"));
        if(status & RDA5807M_STATUS_RDSS)
            Serial.println(F("* RDS Decoder Synchronized"));
        if(status & RDA5807M_STATUS_BLKE)
            Serial.println(F("* RDS Block E Found"));
        if(status & RDA5807M_STATUS_ST)
            Serial.println(F("* Stereo Reception"));
        Serial.println("}");
        Serial.flush();
        break;
      case '?':
        Serial.println(F("Available commands:"));
        Serial.println(F("* v/V     - decrease/increase the volume"));
        Serial.println(F("* s/S     - seek down/up with band wrap-around"));
        Serial.println(F("* m/M     - mute/unmute audio output"));
        Serial.println(F("* f       - display currently tuned frequency"));
        Serial.println(F("* q       - display RSSI for current station"));
        Serial.println(F("* t       - display decoded status register"));
        Serial.println(F("* ?       - display this list"));
        Serial.flush();
        break;
    }
  }
}
void show(int a[])
{
    //выведем цифру a[0] на первый индикатор
  setNumber(a[0]);
  digitalWrite(key1,HIGH);
  delay(2);
  digitalWrite(key1,LOW);
  delay(1);
  //цифра a[1] на второй индикатор
  setNumber(a[1]);
  digitalWrite(key2,HIGH);
  delay(2);
  digitalWrite(key2,LOW);
  delay(1);
  //цифра a[2] на третий индикатор
  setNumber(a[2]);
  digitalWrite(key3,HIGH);
  delay(2);
  digitalWrite(key3,LOW);
  delay(1);
  //выведем цифру a[3] на четвертый индикатор
  setNumber(a[3]);
  digitalWrite(key4,HIGH);
  delay(2);
  digitalWrite(key4,LOW);
  delay(1);
  //выведем цифру a[4] на пятый индикатор
  setNumber(a[4]);
  digitalWrite(key5,HIGH);
  delay(2);
  digitalWrite(key5,LOW);
  delay(1);
}

void setNumber(int num) 
{
  switch (num)
  {
    case 0:
    digitalWrite (out1,LOW);
    digitalWrite (out2,LOW);
    digitalWrite (out4,LOW);
    digitalWrite (out8,LOW);
    break;
    case 1:
    digitalWrite (out1,HIGH);
    digitalWrite (out2,LOW);
    digitalWrite (out4,LOW);
    digitalWrite (out8,LOW);
    break;
    case 2:
    digitalWrite (out1,LOW);
    digitalWrite (out2,HIGH);
    digitalWrite (out4,LOW);
    digitalWrite (out8,LOW);
    break;
    case 3:
    digitalWrite (out1,HIGH);
    digitalWrite (out2,HIGH);
    digitalWrite (out4,LOW);
    digitalWrite (out8,LOW);
    break;
    case 4:
    digitalWrite (out1,LOW);
    digitalWrite (out2,LOW);
    digitalWrite (out4,HIGH);
    digitalWrite (out8,LOW);
    break;
    case 5:
    digitalWrite (out1,HIGH);
    digitalWrite (out2,LOW);
    digitalWrite (out4,HIGH);
    digitalWrite (out8,LOW);
    break;
    case 6:
    digitalWrite (out1,LOW);
    digitalWrite (out2,HIGH);
    digitalWrite (out4,HIGH);
    digitalWrite (out8,LOW);
    break;
    case 7:
    digitalWrite (out1,HIGH);
    digitalWrite (out2,HIGH);
    digitalWrite (out4,HIGH);
    digitalWrite (out8,LOW);
    break;
    case 8:
    digitalWrite (out1,LOW);
    digitalWrite (out2,LOW);
    digitalWrite (out4,LOW);
    digitalWrite (out8,HIGH);
    break;
    case 9:
    digitalWrite (out1,HIGH);
    digitalWrite (out2,LOW);
    digitalWrite (out4,LOW);
    digitalWrite (out8,HIGH);
    break;
  }
}

//перебор всех цифр
void scroll(int pause) {
  for (int i = 0; i < 9; i++) {
    int a[] = {i, i, i, i, i};
    show(a);
    delay(pause);
    show(a);
  }
}
erased

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Вс май 17, 2020 8:54 pm

Да, забыл еще написать. Функцию delay() не рекомендуется использовать в ардуине. Эта функция останавливает работу программы! Если ардуина выполняет много задач, то желательно использовать millis(). Эта функция дает возможность просто обходить нужный участок кода на заданное время.

Если будут вопросы по поводу приемника, постараюсь ответить. В принципе мне осталось нарисовать блок вывода на ИН-12. Самое сложное для меня, ибо нет библиотеки для kicad. Ее тоже надо создавать.
erased

gesigor
Сообщения: 48
Зарегистрирован: Пн май 11, 2020 10:12 pm
Откуда: erased

Азбука Ардуино

Сообщение gesigor » Пн июн 08, 2020 10:05 pm

Еще небольшая полезность на ардуине - генератор. На али продают модуль AD9833
Изображение
Модуль маленький по размерам. Может генерировать от 1 Гц до 5 мГц. Синус, треугольник и прямоугольник. Работает как DDS синтезатор. Почему обратил на него внимание? Есть у меня интерес - ловить ЖД - переговоры на частоте 2.130 мГц. Модуляция у них узкая ЧМ. Для гетеродина нужен кварц, но нужной частоты уже не найти. Вот решил из этого модуля сделать гетеродин. Соединил его с arduino nano (фото есть на первой странице). Залил программу:

Код: Выделить всё

#include <SPI.h>
#include <MD_AD9833.h>

#define DATA  11     // 11-й вывод ардуины
#define CLK   13     // 13-й
#define FSYNC 10     // 10-й

MD_AD9833 AD(FSYNC); // Hardware SPI

unsigned long f;

void setup() {
  
AD.begin();
f = 2585000UL;   //задаем частоту
AD.setFrequency(MD_AD9833::CHAN_0, f);
}

void loop() {
 
}
Пока это все на столе.
Видел народ цепляет к этому валкодер, экран, плюс мелочевку и получает полноценный генератор. Так что изучаю.
erased

Аватара пользователя
Pionka
Сообщения: 575
Зарегистрирован: Чт июн 08, 2017 9:18 pm
Откуда: Рязань

Азбука Ардуино

Сообщение Pionka » Чт фев 09, 2023 3:11 pm

Собрал, для пробного использования, радио на чипе RDA5807 , arduino nano и lcd1602
(прект на Github - https://github.com/mathertel/Radio)
в корпусе, напечатанном на 3d принтере (https://www.thingiverse.com/thing:3493717).
Управление - одной кнопкой - перебор по порядку всех 27 станций ФМ, принимаемых в Рязани (частоты записал в скетч-потом список станций подсокращу - до 2-5 ихбранных) . Антенна - небольшая, телескопическая.
Через jack 3,5, можно подключить наушники или внешний усилитель.
На дисплее отображается частота принимаемой станции, информация RDS (если есть на этой станции) и ещё какие-то цифры в правом верхнем углу (пока не разобрался, что это :))
При подключении к ардуино lcd 1602 shield (экран с 6-ю кнопками) можно дополнительно регулировать громкость +- и осуществлять автопоиск станций вверх и вниз по диапазону.
.
ИзображениеИзображениеИзображениеИзображениеИзображение
С уважением, Андрей Александрович.
Не делаю из лампы культа - просто слушаю на ней музыку :)

Аватара пользователя
Pionka
Сообщения: 575
Зарегистрирован: Чт июн 08, 2017 9:18 pm
Откуда: Рязань

Азбука Ардуино

Сообщение Pionka » Ср апр 19, 2023 5:18 pm

Собрал ФМ радио на RDA5807 и Ардуино нано, в корпусе "Мальчиша". Элементы поддержки комплектующих и заднюю крышку, разработал и напечатал на 3d принтере. За основу взята схема и скетч отсюда : http://forklg.ru/viewtopic.php?f=98&t=1173.
Скетч немного подправил.
FM_rda5807_i_tm1637_v3.zip
(57.13 КБ) 31 скачивание
Настройка на станции - кнопками, которые нажимаются через небольшое смещение модернизированного "диска" мальчиша вверх и вниз соответственно. Питание - от аккумулятора 3,7 В, через контроллер заряда. Динамики - от какого-то ноутбука. Стерео. УНЧ - pam8403. Регулятор громкости - от старого компьютерного CD-ROMа. Есть линейный выход (разъём - от старой материнской платы).
Вживую индикатор частоты смотрится лучше и чётче, чем на фото и видео.
Небольшой фотоотчёт:

ИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображениеИзображение
Видео:
https://youtube.com/shorts/hnJ98yzmfjE?feature=share
С уважением, Андрей Александрович.
Не делаю из лампы культа - просто слушаю на ней музыку :)

jmper
Сообщения: 164
Зарегистрирован: Пт фев 19, 2021 9:19 pm
Откуда: Москва

Азбука Ардуино

Сообщение jmper » Чт апр 20, 2023 11:45 am

Pionka писал(а):
Ср апр 19, 2023 5:18 pm
Настройка на станции - кнопками, которые нажимаются через небольшое смещение модернизированного "диска" мальчиша вверх и вниз соответственно.
По коду видно что нет ограничения по краям диапазона, т.е. если нажимать все время вверх (или вниз) индикатор уйдет за 108(88) и дальше.
может закольцевать?
А еще лучше было бы отсканировать весь диапазон и потом перемещаться от станции к станции, не?
Денис

Аватара пользователя
MOT
Сообщения: 2278
Зарегистрирован: Сб дек 16, 2017 7:58 pm
Откуда: Россия, Северный Кавказ, Краснодарский край, г.Армавир

Азбука Ардуино

Сообщение MOT » Чт апр 20, 2023 12:16 pm

jmper, Денис, да думаю в принципе и нет необходимости в дополнительной проверке по диапазону, ведь цифровое табло есть, где частота отображается. Ну а так, думаю, Pionka, Андрею не сложно добавить в код условие.
Меня только смутило, что частоту начинают сканировать со 100 МГц. У нас в городе, например и ниже станции есть. 100 МГц, это вроде как ГОСТ, если Интернет не врёт.

Про условие, можно например так сделать:

if (digitalRead(6) == HIGH){
// если кнопка "Частота вниз" нажата
if (f_ini == 87.5) f_ini = 108
else f_ini=f_ini-0.1
; // уменьшаем значение частоты на 0,1 МГц
setFrequency(f_ini); // передаем новое значение частоты радиомодулю
};

Получится, если доходим до нижнего предела, то частота установится на 108 МГц. Ну и наподобие можно сделать, когда вверх листаем диапазон, только частотку устанавливать на 87.5. Ну это как вариант. Хотя, повторюсь, может это и лишнее. :)
С уважением, Виктор Евгеньевич
Accept Corp.

jmper
Сообщения: 164
Зарегистрирован: Пт фев 19, 2021 9:19 pm
Откуда: Москва

Азбука Ардуино

Сообщение jmper » Чт апр 20, 2023 3:51 pm

MOT писал(а):
Чт апр 20, 2023 12:16 pm
Меня только смутило, что частоту начинают сканировать со 100 МГц. У нас в городе, например и ниже станции есть. 100 МГц, это вроде как ГОСТ, если Интернет не врёт.
Почему со 100 Мгц? насколько я помню, там с какой частоты задашь, с той на начнет сканирование.
Денис

Аватара пользователя
MOT
Сообщения: 2278
Зарегистрирован: Сб дек 16, 2017 7:58 pm
Откуда: Россия, Северный Кавказ, Краснодарский край, г.Армавир

Азбука Ардуино

Сообщение MOT » Чт апр 20, 2023 4:11 pm

jmper, Денис, ну в скетче так. Но эта переменная задаётся в начале кода, т.е. можешь поменять на любую частоту.
Это из ссылки Андрея.
include <Wire.h> // I2C-Library для управления радиомодулем RDA5807
// SDA приемника RDA5807 подключаем к аналоговому входу 4
// SCL приемника RDA5807 подключаем к аналоговому входу 5
#include "TM1637.h" // Библиотека для управления LED дисплеем TM1637
#define CLK 4 // вывод CLC дисплея
#define DIO 5 // вывод DIO дисплея
TM1637 disp(CLK,DIO);
double f_ini=100.000;// Стартовая частота настройки приемника RDA5807. (Можно изменить на нужную).
С уважением, Виктор Евгеньевич
Accept Corp.

jmper
Сообщения: 164
Зарегистрирован: Пт фев 19, 2021 9:19 pm
Откуда: Москва

Азбука Ардуино

Сообщение jmper » Чт апр 20, 2023 4:40 pm

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

Ответить

Вернуться в «Усилители»