Амплитудная модуляция Arduino Uno

Гость
 
   
  long var=1000;
  long rav=1400;
  long qwe=0;
   
  #include <Arduino.h>
  #include <LiquidCrystal.h>
  #include <LCDKeypad.h>
  LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  // Выход генератора -- вывод 11 (PB3, MOSI)
  #define FREQ_OUT_PIN 11
   
   
  extern "C" void setup();
  extern "C" void loop();
   
  // Предварительные декларации функций.
  uint32_t readFreq();
  void setupFreq(uint32_t freq);
   
  // define some values used by the panel and buttons
  int lcd_key = 0;
  int adc_key_in = 0;
  #define btnRIGHT 0
  #define btnUP 1
  #define btnDOWN 2
  #define btnLEFT 3
  #define btnSELECT 4
  #define btnNONE 5
   
  // read the buttons
  int read_LCD_buttons()
  {
  adc_key_in = analogRead(0); // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50) return btnRIGHT;
  if (adc_key_in < 195) return btnUP;
  if (adc_key_in < 380) return btnDOWN;
  if (adc_key_in < 555) return btnLEFT;
  if (adc_key_in < 790) return btnSELECT;
  return btnNONE; // when all others fail, return this...
  }
   
   
  void setup()
  {
  Serial.begin(115200);
  lcd.begin(16, 2); // start the library
  lcd.setCursor(0,0);
  lcd.print("Push the buttons"); // print a simple message
  }
   
   
  void loop()
  {
   
  lcd.setCursor(0,1); // move to the begining of the second line
  lcd_key = read_LCD_buttons(); // read the buttons
   
  switch (lcd_key) // depending on which button was pushed, we perform an action
  {
  case btnRIGHT:
  {
  lcd.print("RIGHT ");
  break;
  }
  case btnLEFT:
  {
  lcd.print("LEFT ");
  break;
  }
  case btnUP:
  {
  lcd.print("UP ");
   
  var=var+1000;
   
  break;
  }
  case btnDOWN:
  {
  lcd.print("DOWN ");
  var=var-1000;
   
  break;
  }
  case btnSELECT:
  {
  lcd.print("SELECT");
  qwe=1;
  break;
  }
  case btnNONE:
  {
  lcd.print("NONE ");
  break;
  }
  }
   
   
   
   
  uint32_t freq = var;
   
   
   
  // Установка частоты.
  setupFreq(freq);
   
  }
   
  // Чтение данных из последовательного порта
  uint32_t readFreq()
  {
   
  }
   
  static const uint16_t prescallers[] = {0, 1, 8, 32, 64, 128, 256, 1024};
   
  // Установка частоты.
  void setupFreq(uint32_t freq)
  {
  freq=var;
  uint32_t ocr = 0; // Временный буфер для хранения значения регистра OCR2A.
  uint8_t prescallerBits = 1; // Биты предделителя.
  uint16_t prescaller = prescallers[prescallerBits]; // Значение предделителя на основе 'prescallerBits'.
   
  TIMSK2 = 0; // Прерывания таймера не нужны -- отключаем.
   
  if (freq) { // Если частота не '0'
  do // Пытаемся подобрать значения регистра OCR2A и предделителя
  // для заданной частоты.
  {
  ocr = F_CPU / freq / 2 / prescaller - 1; // Вычисляем значение для регистра OCR2A.
  if (ocr < 256) // Если значение верное (регистр 8-мибитный и
  // всё, что меньше 256, допустимо).
  {
  break; // Завершаем цикл.
  }
  prescallerBits += 1; // Если значение рагистра OCR2A не допустимо (условие выше не выполняется),
  // увеличиваем значение предделителя (понижаем частоту).
  prescaller = prescallers[prescallerBits]; // Новое значение предделителя.
  }
  while (prescallerBits < 8); // Подбираем значение регистра и предделителя,
  // пока биты предделителя не выходят за допустимые пределы.
  if (ocr < 256) // Если подобрано корректное значение регистра OCR2A.
  {
  digitalWrite(FREQ_OUT_PIN, LOW); // Вывод 11 в '0'.
  pinMode(FREQ_OUT_PIN, OUTPUT); // Вывод 11 как выход.
  // Устанавливаем для таймера 2 режим CTC.
  TCCR2A = (1 << COM2A0) // Задаём смену уровня вывода 11 при совпадении
  // счётчика таймера и регистра OCR2A.
  | (1 << WGM21); // Режим CTC.
  OCR2A = ocr; // Задаём предел счёта (регистр OCR2A).
  TCCR2B = prescallerBits; // Устанавливаем предделитель для таймера.
   
  freq = F_CPU / 2 / prescaller / (ocr + 1); // Вычисляем полученную частоту
  // (она может отличаться от заданной).
   
  Serial.print(F("freq: ")); // Сообщаем о частоте.
  Serial.println(freq);
  lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces over
  lcd.print(freq);
   
  }
  else // Если не смогли подобрать значение регистра OCR2A.
  {
  Serial.println(F("freq: error (wrong value)")); // Сообщаем о неправильных данных.
  }
  } else { // Если частота '0'
  TCCR2B = 0; // Выключаем PWM на ноге 11.
  pinMode(FREQ_OUT_PIN, INPUT); // Ногу 11 делаем входом.
  digitalWrite(FREQ_OUT_PIN, LOW); // Отключаем поддтяжку на ноге 11 (на всякий случай).
  Serial.println(F("freq: off")); // Сообщаем о выключении генератора.
  }
   
  }
   
   



  • © 2022 GitHub, Inc.


ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

функция не имеет смысла:
 

// Чтение данных из последовательного порта
uint32_t readFreq()
{
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707
Offline
Зарегистрирован: 26.05.2017

rk6jcv - это что было? Вы спрашиваете? Хвастаете? Или просто себя плохо контролируете? :)

По коду - во-первых, это не амплитудная модуляция, во-вторых - в настройке таймера ошибка.

В третьих - вы чего добиться то хотели? :)))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

вы чего добиться то хотели? :)))

Чтобы я классненькую картинку в #2 выложил!

rk6jcv (не проверено)

Код рабочий. Правда немного подправлен - убрал лишние строки.

Ничего не хвастаюсь!

Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.

Я с прескалерами и прерываниями не понял.

 

rk6jcv (не проверено)

функция не имеет смысла:
 

1 // Чтение данных из последовательного порта
2 uint32_t readFreq()
3 {
4 }

 

да это рудимент от исходного кода.

rkit
Offline
Зарегистрирован: 23.11.2016

rk6jcv пишет:

Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.

Как в статье, наверно. А вообще - никак. Цапа в уно нет.

b707
Offline
Зарегистрирован: 26.05.2017

rk6jcv пишет:

Код рабочий.

рабочий код - это тот, что делает ровно то, для чего написан. А ваш, судя по вопросу - пока только компилируется... Это большая разница.

Поэтому начните с четкого описания. что должен делать код, что делает тот, что выше - и в чем между этим разница.

rk6jcv (не проверено)

У меня описание вопроса удалилось. поэтому неразбериха.

 

rk6jcv (не проверено)

На первой странице код для Ардуино Уно и OSEPP LCD and keypad shield.

Я делаю генератор меандра средствами только Ардуино Уно.

Нужна модуляция сигналом 1000 герц (не критично можно от 500 до 1500)

Все работает как задумывадось, но модуляцию не смог сделать как в статье на Хабре

https://habr.com/ru/company/ruvds/blog/598955/

 

 

ad shield

rk6jcv (не проверено)

Если можете помогите и здесь в этом проекте.

Может Вам здесь проще подправить код.

Тоже нужна модуляция на ноге 9 (там где выходит 888 Кгц)

https://www.youtube.com/watch?v=Uud0jqi-vPk видео проэкта

https://www.qrz.ru/software/download/634 файл кода

 

rk6jcv (не проверено)

Это пример модуляции меадра  которая нужна.

rk6jcv (не проверено)

Не понял

Green
Offline
Зарегистрирован: 01.10.2015

rk6jcv пишет:
Это пример модуляции меадра  которая нужна.


Если нужна, тогда сюда.

rkit
Offline
Зарегистрирован: 23.11.2016

rk6jcv пишет:

Это пример модуляции меадра  которая нужна.

Это пример того, как не пользоваться осциллографом.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

rk6jcv пишет:

Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.

Как в статье, наверно. А вообще - никак. Цапа в уно нет.

analogWrite(11, 127);

кое-что о маяках есть тут

rkit
Offline
Зарегистрирован: 23.11.2016

ua6em пишет:

analogWrite(11, 127);

И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?

по всей видимости в коде:
 

   static void point()  //Метод, который описывает поведение ТОЧКА
    {
      byte BrightLed = 255;
      analogWrite(LED_PIN, BrightLed);

      static uint32_t reqfreq = 888000;
      uint32_t ocr = OCR1A;  uint16_t divider = 1;  float freq;
      ocr = (F_CPU / reqfreq / 2 / divider);
      byte shifts[] = {3, 3, 2, 2};
      for (byte i = 0; i < 4; i++) {
        if (ocr > 65536) {
          divider <<= shifts[i];
          ocr = F_CPU / reqfreq / 2 / divider;
        }
        else {
          TCCR1B = (i + 1) | (1 << WGM12);   //Mode4 (CTC)
          break;
        }
      }
      OCR1A = ocr - 1; TCCR1A = 1 << COM1A0;
      freq = (float) F_CPU / 2 / (OCR1A + 1) / divider;

      delay(250);
      analogWrite(LED_PIN, 0);
      TCCR1A = 0; TCCR1B = 0;
      delay(250);
    }

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rk6jcv пишет:

Если можете помогите и здесь в этом проекте.

Может Вам здесь проще подправить код.

Тоже нужна модуляция на ноге 9 (там где выходит 888 Кгц)

https://www.youtube.com/watch?v=Uud0jqi-vPk видео проэкта

https://www.qrz.ru/software/download/634 файл кода

 

Пробуй, может заработает, код под NANO здесь!

rkit
Offline
Зарегистрирован: 23.11.2016

ua6em пишет:

rkit пишет:

И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?

по всей видимости в коде:
 

   static void point()  //Метод, который описывает поведение ТОЧКА
    {
      byte BrightLed = 255;
      analogWrite(LED_PIN, BrightLed);

      static uint32_t reqfreq = 888000;
      uint32_t ocr = OCR1A;  uint16_t divider = 1;  float freq;
      ocr = (F_CPU / reqfreq / 2 / divider);
      byte shifts[] = {3, 3, 2, 2};
      for (byte i = 0; i < 4; i++) {
        if (ocr > 65536) {
          divider <<= shifts[i];
          ocr = F_CPU / reqfreq / 2 / divider;
        }
        else {
          TCCR1B = (i + 1) | (1 << WGM12);   //Mode4 (CTC)
          break;
        }
      }
      OCR1A = ocr - 1; TCCR1A = 1 << COM1A0;
      freq = (float) F_CPU / 2 / (OCR1A + 1) / divider;

      delay(250);
      analogWrite(LED_PIN, 0);
      TCCR1A = 0; TCCR1B = 0;
      delay(250);
    }

 

Это ШИМ

rk6jcv (не проверено)

Код работает!!!!!!! Амплитудная модуляция есть!!!!! Пробуй, может заработает, код под NANO здесь!

// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)
  // Для тактовой 16 мегагерц
  TCCR1A = 1<<COM1A0;                      // CTC mode to OCR1A
  TCCR1B = 1 <<WGM12 | 1<<CS10;           // Clock/1
  OCR1A = 14; 
 
Как получается частота 571 Кгц????
 
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Писец!

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

rk6jcv пишет:

// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)

  // Для тактовой 16 мегагерц
  TCCR1A = 1<<COM1A0;                      // CTC mode to OCR1A
  TCCR1B = 1 <<WGM12 | 1<<CS10;           // Clock/1
  OCR1A = 14; 
 
Как получается частота 571 Кгц????
 
 
Действительно, почему 571 а не 533 ? :)
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

dimax пишет:

rk6jcv пишет:

// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)

  // Для тактовой 16 мегагерц
  TCCR1A = 1<<COM1A0;                      // CTC mode to OCR1A
  TCCR1B = 1 <<WGM12 | 1<<CS10;           // Clock/1
  OCR1A = 14; 
 
Как получается частота 571 Кгц????
 
 
Действительно, почему 571 а не 533 ? :)

потому что в оригинале OCR1A = 13 )))

rk6jcv (не проверено)

// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)

  // Для тактовой 16 мегагерц
  TCCR1A = 1<<COM1A0;                      // CTC mode to OCR1A
  TCCR1B = 1 <<WGM12 | 1<<CS10;           // Clock/1
  OCR1A = 13; 
 
Как получается частота 571 Кгц????
Да, я изменил значение 13 на 14 - пытался понять закономерность Как получается эта частота 571 ???
16000:13=1230:2=615 в итоге??? Если 13 это делитель, то результат неясен.
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Делением тактовой частоты

fOCnx= (fclk_I/O)  /  (2  х  N  х  ( 1 + OCRnx))
The N variable represents the prescale factor (1, 8, 32, 64, 128, 256, or 1024).

Да, я код поправил, антенна на 9 пине, зуммер на 11

rk6jcv (не проверено)

ua6em я Вам письмо отправил на Яндекс почту.

За помощь спасибо всем!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Писец!

Христофор не читатель? )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rk6jcv пишет:

ua6em я Вам письмо отправил на Яндекс почту.

За помощь спасибо всем!

хорошо! посмотрю! Если константу чуток поправить, то телеграф приемлемый, а то заснуть можно:
const uint8_t Dot = 2;

rk6jcv (не проверено)
ЕвгенийП пишет:

Писец!

А что удивляетесь???? Учусь только!!!!!!!!!!!! Здесть на то и форум чтобы спросить можно было?

rk6jcv (не проверено)

ua6em пишет:

rk6jcv пишет:

ua6em я Вам письмо отправил на Яндекс почту.

За помощь спасибо всем!

хорошо! посмотрю! Если константу чуток поправить, то телеграф приемлемый, а то заснуть можно:
const uint8_t Dot = 2;

Я бы скорость телеграфа понизил - для обучения самое то.

b707
Offline
Зарегистрирован: 26.05.2017

rk6jcv пишет:

А что удивляетесь???? Учусь только!!!!!!!!!!!! Здесть на то и форум чтобы спросить можно было?

вы нифига не учитесь, вы выклянчиваете готовое решение. Вам 2 дня назад дали ссылку, где подробно описано, как получаются ваши 571 КГц. Вы за два дня так и удосужились прочитать. хотя там всего несколько страниц.

Скажите спасибо, что Ua6en вам сочувствует как радиолюбителю, а то при таком хамском отношении вам никто ничем помогать не стал бы

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

да пропали ссылки что-то, пропали, на статью где Евгений  разъясняет работу таймеров...

И второе, нагрузить лучше на параллельный контур работающий на резонансной частоте на отвод витка снизу, но так, чтобы ток пина не превышал 20-30 ма, через конденсатор, отрезав постоянную составляющую

да, о модуляции, это оно:
 

// Interrupt modulates carrier at 644Hz
	ISR (TIMER2_COMPA_vect) {
	  TCCR1B = TCCR1B ^ 1<<CS10;
	}