Амплитудная модуляция Arduino Uno
- Войдите на сайт для отправки комментариев
Втр, 04/01/2022 - 18:24
| 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")); // Сообщаем о выключении генератора. | |
| } | |
| } | |
функция не имеет смысла:
// Чтение данных из последовательного порта uint32_t readFreq() { }rk6jcv - это что было? Вы спрашиваете? Хвастаете? Или просто себя плохо контролируете? :)
По коду - во-первых, это не амплитудная модуляция, во-вторых - в настройке таймера ошибка.
В третьих - вы чего добиться то хотели? :)))
вы чего добиться то хотели? :)))
Чтобы я классненькую картинку в #2 выложил!
Код рабочий. Правда немного подправлен - убрал лишние строки.
Ничего не хвастаюсь!
Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.
Я с прескалерами и прерываниями не понял.
функция не имеет смысла:
расечатать?
1// Чтение данных из последовательного порта2uint32_t readFreq()3{4}да это рудимент от исходного кода.
Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.
Как в статье, наверно. А вообще - никак. Цапа в уно нет.
Код рабочий.
рабочий код - это тот, что делает ровно то, для чего написан. А ваш, судя по вопросу - пока только компилируется... Это большая разница.
Поэтому начните с четкого описания. что должен делать код, что делает тот, что выше - и в чем между этим разница.
У меня описание вопроса удалилось. поэтому неразбериха.
На первой странице код для Ардуино Уно и OSEPP LCD and keypad shield.
Я делаю генератор меандра средствами только Ардуино Уно.
Нужна модуляция сигналом 1000 герц (не критично можно от 500 до 1500)
Все работает как задумывадось, но модуляцию не смог сделать как в статье на Хабре
https://habr.com/ru/company/ruvds/blog/598955/
ad shield
Если можете помогите и здесь в этом проекте.
Может Вам здесь проще подправить код.
Тоже нужна модуляция на ноге 9 (там где выходит 888 Кгц)
https://www.youtube.com/watch?v=Uud0jqi-vPk видео проэкта
https://www.qrz.ru/software/download/634 файл кода
Это пример модуляции меадра которая нужна.
Не понял
Если нужна, тогда сюда.
Это пример модуляции меадра которая нужна.
Это пример того, как не пользоваться осциллографом.
Спрашиваю 100%. как мне сделать амплитудную модуляцию на 11 ноге, как в статье в Хабре.
Как в статье, наверно. А вообще - никак. Цапа в уно нет.
analogWrite(11, 127);
кое-что о маяках есть тут
analogWrite(11, 127);
И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?
И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?
по всей видимости в коде:
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); }Если можете помогите и здесь в этом проекте.
Может Вам здесь проще подправить код.
Тоже нужна модуляция на ноге 9 (там где выходит 888 Кгц)
https://www.youtube.com/watch?v=Uud0jqi-vPk видео проэкта
https://www.qrz.ru/software/download/634 файл кода
Пробуй, может заработает, код под NANO здесь!
И где тут амплитудная модуляция? Где сигнал, наложенный на амплитуду несущей?
по всей видимости в коде:
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); }Это ШИМ
Код работает!!!!!!! Амплитудная модуляция есть!!!!! Пробуй, может заработает, код под NANO здесь!
Писец!
// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)
// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)
потому что в оригинале OCR1A = 13 )))
// Set up Timer/Counter1 to generate 571kHz (571.42856)(PIN D9)
Делением тактовой частоты
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
ua6em я Вам письмо отправил на Яндекс почту.
За помощь спасибо всем!
Писец!
Христофор не читатель? )))
ua6em я Вам письмо отправил на Яндекс почту.
За помощь спасибо всем!
хорошо! посмотрю! Если константу чуток поправить, то телеграф приемлемый, а то заснуть можно:
const uint8_t Dot = 2;
Писец!
А что удивляетесь???? Учусь только!!!!!!!!!!!! Здесть на то и форум чтобы спросить можно было?
ua6em я Вам письмо отправил на Яндекс почту.
За помощь спасибо всем!
хорошо! посмотрю! Если константу чуток поправить, то телеграф приемлемый, а то заснуть можно:
const uint8_t Dot = 2;
Я бы скорость телеграфа понизил - для обучения самое то.
А что удивляетесь???? Учусь только!!!!!!!!!!!! Здесть на то и форум чтобы спросить можно было?
вы нифига не учитесь, вы выклянчиваете готовое решение. Вам 2 дня назад дали ссылку, где подробно описано, как получаются ваши 571 КГц. Вы за два дня так и удосужились прочитать. хотя там всего несколько страниц.
Скажите спасибо, что Ua6en вам сочувствует как радиолюбителю, а то при таком хамском отношении вам никто ничем помогать не стал бы
да пропали ссылки что-то, пропали, на статью где Евгений разъясняет работу таймеров...
И второе, нагрузить лучше на параллельный контур работающий на резонансной частоте на отвод витка снизу, но так, чтобы ток пина не превышал 20-30 ма, через конденсатор, отрезав постоянную составляющую
да, о модуляции, это оно:
// Interrupt modulates carrier at 644Hz ISR (TIMER2_COMPA_vect) { TCCR1B = TCCR1B ^ 1<<CS10; }