0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
1

Считывание аналогового сигнала с нескольких каналов ATmega328

17.03.2023, 14:42. Показов 383. Ответов 12
Метки нет (Все метки)

Добрый день. Начал разработку регулятора напряжения, на основании имеющейся схемы.
Столкнулся с проблемой, как считывать данные одновременно с нескольких аналоговых портов на Arduino Nano? Нужно считать напряжение с А3 и А2 для расчета мощности. В данный момент, симистор работает, а Arduino Nano считывает с него напряжение через А1!
Вложения
Тип файла: rar U_REG_LCD.rar (4.2 Кб, 15 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.03.2023, 14:42
Ответы с готовыми решениями:

Измерение нескольких каналов АЦП один раз за период сигнала запуска
Всем привет! Встал в тупик с частью программы Работаю с АЦП. Нужно произвести последовательное...

Проект платы аналогового реобаса на несколько каналов.
Доброго времени суток, форумчане, DiHAlt. Задумал тут сделать на базе аналогового реобаса...

Обработка аналогового сигнала
Доброго времени суток! Решил сделать автомобильный тахометр, который не требует подключения ни к...

Преобразование аналогового сигнала
Добрый день. Хочу заменить штатный датчик уровня топлива на ёмкостной. Схема подключения штатного...

12
Модератор
Эксперт по электронике
8789 / 6574 / 892
Регистрация: 14.02.2011
Сообщений: 23,083
17.03.2023, 14:50 2
Цитата Сообщение от VladimiV Посмотреть сообщение
Столкнулся с проблемой, как считывать данные одновременно с нескольких аналоговых портов
никак
там стоит мультиплексор, сначала считывается один канал, потом второй и так далее
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
17.03.2023, 15:06  [ТС] 3
Это лучший ответ, который я видел. Зачем тратить время для написания такого ответа? Мне не понятно как программно настроить АЦП и подготовить его к считыванию данных с прерыванием.
0
49 / 12 / 6
Регистрация: 06.03.2022
Сообщений: 125
17.03.2023, 19:58 4
А какой должен быть ответ, если код даже не компилируется?
Откуда хоть взяли?
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
17.03.2023, 21:21  [ТС] 5
Не компилируется, потому что вписал пару переменных! В сообщениях об ошибках отображается при компиляции, так как хотел присвоить считанные значения переменным и вывести на LCD дисплей, но столкнулся с проблемой описанной в данном посте. Никакого криминала в этом не вижу!
0
49 / 12 / 6
Регистрация: 06.03.2022
Сообщений: 125
17.03.2023, 21:26 6
Код писали сами? Или он откуда-то?
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
17.03.2023, 21:34  [ТС] 7
Взял с GitHub.
0
49 / 12 / 6
Регистрация: 06.03.2022
Сообщений: 125
17.03.2023, 21:43 8
Ссылочку киньте, я посмотрю. А вообще на гитхабе есть обратная связь с разработчиком.
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
18.03.2023, 12:44  [ТС] 9
К сожалению, ссылку утерял.
0
49 / 12 / 6
Регистрация: 06.03.2022
Сообщений: 125
18.03.2023, 14:06 10
А как хоть название проекта?
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
18.03.2023, 15:02  [ТС] 11
Как и название файла
0
0 / 0 / 0
Регистрация: 17.05.2022
Сообщений: 10
18.03.2023, 17:14  [ТС] 12
Проверьте пожалуйста логику, верна?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ISR(ADC_vect) {
  switch (a_band) {
    case 1:                                 // преобразование (A1)
      byte An_pin = ADCL;
      byte An = ADCH;
      Uism = ((An << 8) + An_pin) - 512;
      Uism *= Uism;                          // возводим значение в квадрат
      Usumm += Uism;                        // складываем квадраты измерений
      cntr++;                               // начинаем с начальной полосы                              ->band init
      cFlag(ADMUX, 0xF);                    // новая полоса для преобразования
      sFlag(ADMUX, a_band);   
      ADCSRA |= BIT(ADSC);                  // начинаем новое измерение
    case 2:                                 // преобразование (A2)
      byte An_pin = ADCL;
      byte An = ADCH;
      Uw = ((An << 8) + An_pin) - 512;
      cFlag(ADMUX, 0xF);                    // новая полоса для преобразования
      sFlag(ADMUX, a_band);   
      ADCSRA |= BIT(ADSC);                  // начинаем новое измерение
    case 3:                                 // преобразование (A3)
      byte An_pin = ADCL;
      byte An = ADCH;
      Iw = ((An << 8) + An_pin) - 512;
      cFlag(ADMUX, 0xF);                    // новая полоса для преобразования
      sFlag(ADMUX, a_band);   
      ADCSRA |= BIT(ADSC);                  // начинаем новое измерение
      break;
      return;   
  }
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void setup() {
  Serial.begin(9600);
  pinMode(detect, INPUT_PULLUP);             //детектор нуля
  pinMode(BUTTON_PLUS, INPUT_PULLUP);        //кнопки, входы
  pinMode(BUTTON_MINUS, INPUT_PULLUP);
  pinMode(BUTTON_SET, INPUT_PULLUP);
  pinMode(ACCELERATOR, INPUT_PULLUP);
  pinMode(STOP, INPUT_PULLUP);
  pinMode(triac, OUTPUT);                    //симистор
  lcd.begin(16, 2);                          //Initialise 16*2 LCD
  if ((EEPROM.read(EE_INIT_ADDR) != 1) || (buffer_ust_U > 265) || (buffer_ust_U < 0)) { //Первый запуск или некорректные значения
    first_start();
  }
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Wattmeter");
  lcd.setCursor(3, 1);
  lcd.print("V 0_1");
  _delay_ms(2000);
  lcd.clear();
  cFlag(PRR, BIT(PRADC));                       // убеждаемся, что на АЦП подано питание
                                                // ADMUX.REFS[1:0] = опорное напряжение AREF
                                                // ADMUX.ADLAR = результат преобразования по правому краю (для 10-бит данных) (ADCL, затем ADCH)
                                                // ADMUX.MUX[3:0] = a_band - выбранный вход АЦП
    ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | a_band;
                                                // запрещают использование входов ADC5 - ADC0 как цифровых
    sFlag(DIDR0, BIT(ADC5D) | BIT(ADC4D) | BIT(ADC3D) | BIT(ADC2D) | BIT(ADC1D) | BIT(ADC0D));
                                                // ADCSRA.ADEN = включаем АЦП
                                                // ADCSRA.ADSC = запускаем преобразование до прерывания
                                                // ADCSRA.ADATE = ручной запуск преобразования
                                                // ADCSRA.ADIF = игнорируем признак состоявшегося прерывания
                                                // ADCSRA.ADIE = разрешаем прерывания
                                                // ADCSRA.ADPS[2:0] = устанавливаем делитель на 32
                                                // частота ADC clock будет 250кГц, один такт будет соответствовать 4мкс, время одного преобразования - 60мкс
    ADCSRA = (1<<ADEN) | (1<<ADSC) | (0<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
 
  //====================================================== Таймер задержки времени открытия триака после детектирования нуля (0 триак не откроется)
  TCCR1A = 0x00;
  TCCR1B = 0x00;   
  TCCR1B = (1 << CS12) | (0 << CS11) | (0 << CS10); // Тактирование от CLK.
  OCR1A = 0;                                        // Верхняя граница счета. Диапазон от 0 до 65535.
                                                    // Частота прерываний будет = Fclk/(N*(1+OCR1A)), где N - коэф. предделителя (1, 8, 64, 256 или 1024)
  TIMSK1 |= (1 << OCIE1A);                          // Разрешить прерывание по совпадению
  attachInterrupt(1, zero_crosss_int, RISING);
}
0
590 / 353 / 67
Регистрация: 21.09.2008
Сообщений: 1,207
19.03.2023, 08:19 13
Цитата Сообщение от VladimiV Посмотреть сообщение
К сожалению, ссылку утерял.
Какая пичалька.
Цитата Сообщение от janis Посмотреть сообщение
А как хоть название проекта?
Цитата Сообщение от VladimiV Посмотреть сообщение
Как и название файла
Ничего подобного не нашёл на github.com ни непосредственно, ни гуглением. IMHO, автор "мутит воду", наводя тень на плетень. Но зачем?
В операторе switch каждая ветка case должна заканчиваться оператором break, иначе при a_band==2 последовательно выполнятся ветки 2 и 3, а первая будет пропущена. Смысл уловили?
Выход из прерывания должен быть как можно более быстрым. В прерывании нельзя делать "тяжелые" вычисления, их нужно вытаскивать наружу. У Вас же там умножение, что не является легковесной операцией.
C
1
2
3
      byte An_pin = ADCL;
      byte An = ADCH;
      Uism = ((An << 8) + An_pin) - 512;
Зачем? avr-gcc позволяет так:
C
1
Uism = ADCW - 512;
При оптимизации можно указывать для переменных ключевое слово-подсказку register.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.03.2023, 08:19
Помогаю со студенческими работами здесь

Растяжка аналогового сигнала.
Что-то я откровенно туплю по жаре. Есть у меня очееень медленно изменяющийся (можно считать...

Измерение аналогового сигнала
Здравствуйте Уважаемые знатоки!!! Обращаюсь к вам за помощью. Аналоговый сигнал поступает на АЦП...

Реализация аналогового сигнала
Здравствуйте , нужно с помощью цап на микроконтроллере синтезировать периодический аналоговый...

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

Измеритель периода аналогового сигнала
Здравствуйте!Необходимо разработать программу,считающую период аналогового сигнала на...

Дискретизация и квантование аналогового сигнала(косинуса)
Нужно реализовать алгоритм преобразования аналогового сигнала F(x) в цифровой сигнал на...

Спектральная плотность непериодического аналогового сигнала
Здравствуйте! Не могу правильно рассчитать спектральную плотность сигнала. Вот что получилось:


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru