Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

Ответ

Непрочитано 18.03.2014, 19:18   #1

mikesmith

Администратор

 
Аватар для mikesmith
 

Регистрация: 10.05.2003

Сообщений: 2,102

Сказал спасибо: 547

Сказали Спасибо 2,614 раз(а) в 510 сообщении(ях)

mikesmith на пути к лучшему
По умолчанию Графический анализатор спектра на Arduino

Надо было тут кое-куда быстро прикрутить сию конструкцию. Делюсь с вами.

Имеем Arduino Uno и дисплей на светодиодных матрицах (когда-то давно покупал на ибее: http://www.ebay.com/itm/LED-Lattice-...-/400375652285 )

В протоколе дисплея можно разобраться по исходнику, переписав функцию вывода столбцов на него, можно использовать любой дисплей, можно и на MAX7219 собрать).

Использовал готовую библиотеку FFT - по Фурье раскладывает спектр. Функция возвращает массив из 64 значений, а значит можно использовать дисплей 64х16, будет зрелищнее)) Три режима - сплошные столбики, пиковые точки и смешанный режим.

Вторая библиотека - TimerOne. Пришлось использовать прерывание, из-за того, что в свободном цикле функция преобразования Фурье работает слишком долго, а моя платка индикаторов без памяти (с MAX7219/21 можно будет рисовать без прерывания), и контроллер не успевает регенерировать картинку.

В конечном итоге все это будет собрано на Arduino Mini (2.5$) и 8 матричных индикаторах с MAX7219 на каждом (5$+4$), т.е будет 32-полосный эквалайзер. Операционник LM386 (первое, что было под рукой). Печатка, кнопка, пассивные детальки... Цена конструкции выйдет баксов 15. Неплохо))

Фотки, "схемка", исходник/скетч, библиотека FFT и видео - во вложении. Будут вопросы по программе и некоторым нюансам, задавайте - отвечу. Пользуйтесь на здоровье, дорогие форумчане!

Видео работы:

Видео:

Миниатюры:

Нажмите на изображение для увеличения
Название: 20140318_183551.jpg
Просмотров: 793
Размер: 78.1 Кб
ID: 60945   Нажмите на изображение для увеличения
Название: eq.png
Просмотров: 1664
Размер: 172.2 Кб
ID: 61062  

Вложения:

Тип файла: rar eq.rar (242.6 Кб, 630 просмотров)
mikesmith вне форума   Ответить с цитированием
Эти 9 пользователя(ей) сказали Спасибо mikesmith за это сообщение:

291066 (20.05.2014), Bass85 (23.03.2014), justnsn (19.03.2014), Marc2005 (19.03.2014), Niki43 (20.04.2016), nsl2004 (19.03.2014), serega27109 (10.11.2016), switch0 (04.08.2014), vasska (27.06.2017)

Меню пользователя mikesmith
Непрочитано 18.03.2014, 19:21   #2

mikesmith

Администратор

 
Аватар для mikesmith
 

Регистрация: 10.05.2003

Сообщений: 2,102

Сказал спасибо: 547

Сказали Спасибо 2,614 раз(а) в 510 сообщении(ях)

mikesmith на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Код:
#include  // Библиотека для таймера
#include   // Библиотека для преобразований Фурье

int i = 0;
int v[16], w[16];
char im[128], data[128];
int ModeState = 0; // Режим отображения: 0 - Обычный, 1 - Пиковые значения, 2 - Смешанный  
boolean ButtonModeState = false;

int D_port = 7;
int C_port = 6;
int B_port = 5;
int A_port = 4;
int G_port = 3;
int DI_port = 2;
int CLK_port = 1;
int Latch_port = 0;
int Sound_input = A0;
const int ButtonModePin = 8;

void setup()
{
ADCSRA = (1<<ADEN)|(1<<ADPS0)|(0<<ADPS1)|(1<<ADPS2); // Устанавливаем частоту дискретизации АЦП - sps=500k ~f=10k
analogReference(DEFAULT); // Опорное напряжение для AЦП - 5 вольт
pinMode(ButtonModePin, INPUT); // Вход, к которому подключена кнопка выбора режимов
digitalWrite(ButtonModePin, HIGH); // Подключаем подтягивающий (+) резистор к кнопке
pinMode(D_port, OUTPUT); // Выводы индикатора
pinMode(C_port, OUTPUT);
pinMode(B_port, OUTPUT);
pinMode(A_port, OUTPUT);
pinMode(G_port, OUTPUT);
pinMode(DI_port, OUTPUT);
pinMode(CLK_port, OUTPUT);
pinMode(Latch_port, OUTPUT);
Timer1.initialize(10000); // Инициализируем прерывания по таймеру для вывода данных на дисплей
Timer1.attachInterrupt(Timer1_action);
}

void Timer1_action() // Обработка прерывания от таймера - перерисовываем дисплей
{
for (int t=0;t<16;t++)
    {
    HC595_Data_Send(v[t], t);
    delayMicroseconds(200);
    }
delayMicroseconds(300);
digitalWrite(G_port, 1);
}

void HC595_Data_Send(int da, int han) // Процедура вывода одного столбца на дисплей
{
digitalWrite(Latch_port, 0);
digitalWrite(CLK_port, 0);
for (int i=16;i>0;i--)
  {
  if (ModeState == 0) // обычный режим
    {
    if (da > i) digitalWrite(DI_port, 0); else digitalWrite(DI_port, 1);
    }
  if (ModeState == 1) // пиковый режим
    {
    if (da == i+1) digitalWrite(DI_port, 0); else digitalWrite(DI_port, 1);
    }
  if (ModeState == 2) // смешанный режим
    {
    if (da > 7)
      {
      if (da == i-1 || da > i) digitalWrite(DI_port, 0); else digitalWrite(DI_port, 1);
      } 
      else
      {
      if (da > i) digitalWrite(DI_port, 0); else digitalWrite(DI_port, 1);
      }    
    }
  digitalWrite(CLK_port, 1);
  digitalWrite(CLK_port, 0);
  }
digitalWrite(G_port, 1);
switch (han)
  {
  case 0:  digitalWrite(A_port, 0); digitalWrite(B_port, 0); digitalWrite(C_port, 0); digitalWrite(D_port, 0); break;
  case 1:  digitalWrite(A_port, 1); digitalWrite(B_port, 0); digitalWrite(C_port, 0); digitalWrite(D_port, 0); break;
  case 2:  digitalWrite(A_port, 0); digitalWrite(B_port, 1); digitalWrite(C_port, 0); digitalWrite(D_port, 0); break;
  case 3:  digitalWrite(A_port, 1); digitalWrite(B_port, 1); digitalWrite(C_port, 0); digitalWrite(D_port, 0); break;
  case 4:  digitalWrite(A_port, 0); digitalWrite(B_port, 0); digitalWrite(C_port, 1); digitalWrite(D_port, 0); break;
  case 5:  digitalWrite(A_port, 1); digitalWrite(B_port, 0); digitalWrite(C_port, 1); digitalWrite(D_port, 0); break;
  case 6:  digitalWrite(A_port, 0); digitalWrite(B_port, 1); digitalWrite(C_port, 1); digitalWrite(D_port, 0); break;
  case 7:  digitalWrite(A_port, 1); digitalWrite(B_port, 1); digitalWrite(C_port, 1); digitalWrite(D_port, 0); break;
  case 8:  digitalWrite(A_port, 0); digitalWrite(B_port, 0); digitalWrite(C_port, 0); digitalWrite(D_port, 1); break;
  case 9:  digitalWrite(A_port, 1); digitalWrite(B_port, 0); digitalWrite(C_port, 0); digitalWrite(D_port, 1); break;
  case 10: digitalWrite(A_port, 0); digitalWrite(B_port, 1); digitalWrite(C_port, 0); digitalWrite(D_port, 1); break;
  case 11: digitalWrite(A_port, 1); digitalWrite(B_port, 1); digitalWrite(C_port, 0); digitalWrite(D_port, 1); break;
  case 12: digitalWrite(A_port, 0); digitalWrite(B_port, 0); digitalWrite(C_port, 1); digitalWrite(D_port, 1); break;
  case 13: digitalWrite(A_port, 1); digitalWrite(B_port, 0); digitalWrite(C_port, 1); digitalWrite(D_port, 1); break;
  case 14: digitalWrite(A_port, 0); digitalWrite(B_port, 1); digitalWrite(C_port, 1); digitalWrite(D_port, 1); break;
  case 15: digitalWrite(A_port, 1); digitalWrite(B_port, 1); digitalWrite(C_port, 1); digitalWrite(D_port, 1); break;
  }
digitalWrite(Latch_port, 1);
digitalWrite(G_port, 0);
digitalWrite(Latch_port, 0);
}

void loop()
{
for (i=0;i<128;i++) // Считываем значение с аналогового входа в массив 
  {
  data[i] = analogRead(Sound_input);
  im[i] = 0;  
  }
fix_fft(data, im, 7, 0); // Преобразование Фурье
for (i=0;i<64;i++)
  {
  data[i] = sqrt(data[i]  data[i] + im[i]  im[i]); // Считаем и делаем значения положительными
  }
for (i=1;i<16;i++) // Считаем значение для каждого столбца (отбрасываем первый - там помехи и фон 50Гц)
  {
  w[i] = v[i];
  v[i] = (data[i4] + data[i4+1] + data[i4+2] + data[i4+3])/4; // Считаем среднее арифметическое соседних столбцов, так как у нас их всего 16, а в массиве 64
  if (v[i] > 15) v[i] = 15;
  if (v[i] < w[i]) v[i] = w[i]-0.1; // Плавное угасание столбцов, как в профессиональном эквалайзере
  }
v[0] = v[1]/2; // Значение первого столбца самых нижних частот (в котором фон 50Гц) получаем, разделив следующий на 2

if (digitalRead(ButtonModePin) == LOW&&!ButtonModeState) // Обработка кнопочных нажатий 
  {
  ModeState = ++ModeState;
  if (ModeState > 2) ModeState = 0;
  ButtonModeState = true;
  delay(5);
  } 
if (digitalRead(ButtonModePin) == HIGH&&ButtonModeState)
  {
  ButtonModeState = false;
  delay(5);
  } 
}
mikesmith вне форума   Ответить с цитированием
Эти 6 пользователя(ей) сказали Спасибо mikesmith за это сообщение:

Marc2005 (19.03.2014), OneginForte (19.03.2014), ravas (19.03.2014), raxp (18.03.2014), switch0 (19.03.2014), tele_puz (20.03.2014)

Меню пользователя mikesmith
Непрочитано 20.03.2014, 10:59   #3

tele_puz

Прописка

 
Аватар для tele_puz
 

Регистрация: 13.03.2007

Сообщений: 135

Сказал спасибо: 7

Сказали Спасибо 32 раз(а) в 17 сообщении(ях)

tele_puz на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Спасибо, грамотно сделано!

tele_puz на форуме   Ответить с цитированием

Меню пользователя tele_puz
Непрочитано 20.03.2014, 12:15   #4

mikesmith

Администратор

 
Аватар для mikesmith
 

Регистрация: 10.05.2003

Сообщений: 2,102

Сказал спасибо: 547

Сказали Спасибо 2,614 раз(а) в 510 сообщении(ях)

mikesmith на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Спасибо. Кстати, не помешает 100К резистор между землей и катодом диода, чтобы при отсутствии сигнала, на входе АЦП не было фона или помех. Пририсовал его на схемке. Также внес небольшие изменения в код (архив в первом посте уже с изменениями), теперь при отсутствии сигнала нету небольших выбросов на дисплее.

mikesmith вне форума   Ответить с цитированием
Сказали "Спасибо" mikesmith

gans70 (20.03.2014)

Меню пользователя mikesmith
Непрочитано 09.04.2014, 09:52   #5

mikesmith

Администратор

 
Аватар для mikesmith
 

Регистрация: 10.05.2003

Сообщений: 2,102

Сказал спасибо: 547

Сказали Спасибо 2,614 раз(а) в 510 сообщении(ях)

mikesmith на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Друзья, так как я пень пнем в делах аналоговых, нужна ваша "аналоговая" помощь. Настал момент сборки, и нужно нарисовать схемку предусилителя с АРУ.

Питание 5В. Либо на MCP6002, либо на LM358/LM324.

Сигнал будет идти со звуковой карты компьютера, на выходе надо получить сигнал 0-5В. АРУ - обязательно.

Буду признателен за любые советы/наброски.

mikesmith вне форума   Ответить с цитированием

Меню пользователя mikesmith
Непрочитано 04.05.2014, 00:50   #6

fivist

Прохожий

 

Регистрация: 04.05.2014

Сообщений: 9

Сказал спасибо: 0

Сказали Спасибо 0 раз(а) в 0 сообщении(ях)

fivist на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Друзья, подскажите пжалуйста - обираю эту схему! не пойму - если вместо ардуино подключить динамик - то он просто хрипит и звук какойто искаженный, а если поставить кандер на 250мФ как по даташиту то звук боле менее нормальный, так должно быть? я динамик подключал для проверки - пойдет ли сигнал на ардуино. Ардуино пока не подключал...

fivist вне форума   Ответить с цитированием

Меню пользователя fivist
Непрочитано 04.05.2014, 12:08   #7

bass1981

Гражданин KAZUS.RU

 

Регистрация: 01.09.2007

Сообщений: 926

Сказал спасибо: 282

Сказали Спасибо 26 раз(а) в 23 сообщении(ях)

bass1981 на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

АРУ - обязательно.
А это у вас нужно спросить если честно...
Автоматическая Регулировка Усиления.....

Если без АРУ.... То в зависимости от уровня сигнала выдаваемого звуковой картой, нужно будет подстраивать переменный резистор. Который у вас в схеме. Если это устраивает можно и без АРУ.

Если не устраивает то придумываем схему АРУ...
bass1981 вне форума   Ответить с цитированием

Меню пользователя bass1981
Непрочитано 04.05.2014, 12:10   #8

bass1981

Гражданин KAZUS.RU

 

Регистрация: 01.09.2007

Сообщений: 926

Сказал спасибо: 282

Сказали Спасибо 26 раз(а) в 23 сообщении(ях)

bass1981 на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Друзья, подскажите пжалуйста - обираю эту схему! не пойму - если вместо ардуино подключить динамик - то он просто хрипит и звук какойто искаженный, а если поставить кандер на 250мФ как по даташиту то звук боле менее нормальный, так должно быть? я динамик подключал для проверки - пойдет ли сигнал на ардуино. Ардуино пока не подключал...
Динамик имеет сопротивление на много меньше чем вход АЦП на Ардуино.
Делаем выводы.
bass1981 вне форума   Ответить с цитированием

Меню пользователя bass1981
Непрочитано 04.05.2014, 19:35   #9

mikesmith

Администратор

 
Аватар для mikesmith
 

Регистрация: 10.05.2003

Сообщений: 2,102

Сказал спасибо: 547

Сказали Спасибо 2,614 раз(а) в 510 сообщении(ях)

mikesmith на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

fivist, собирайте так, как указано (LM386 - это УЗЧ, его я поставил только потому, что ничего больше под рукой не оказалось). Входное сопротивление ардуинки намного выше сопротивления динамика, как вам ответили выше.

В скором времени выложу более навороченный вариант устройства с дисплеем 32х16.

mikesmith вне форума   Ответить с цитированием

Меню пользователя mikesmith
Непрочитано 06.05.2014, 10:53   #10

fivist

Прохожий

 

Регистрация: 04.05.2014

Сообщений: 9

Сказал спасибо: 0

Сказали Спасибо 0 раз(а) в 0 сообщении(ях)

fivist на пути к лучшему
По умолчанию Re: Графический анализатор спектра на Arduino

Уважаемые, собрал такую схему! что в ней не так, постоянно открыты ключи на BC557 транзисторе, в матрице столбец постоянно светится, digitalWrite(номер пина, HIGH); или digitalWrite(номер пина, LOW); ничего не дают. Может я не так что то подключаю? что сдесь не правильно?


пример тестового скетча:

#include 
enum { REG = 8 }; // пин, управляющий защёлкой (SS в терминах SPI)


int col_1 = 2;
int col_2 = 3;
int col_3 = 4;
int col_4 = 5;
int col_5 = 6;
int col_6 = 7;
int col_7 = 9;

/ Теперь шлём по 16 бит. Важный момент: так как по умолчанию
  данные передаются, начиная со старшего бита, сначала нужно
  послать старший байт, затем - младший - тогда всё 16 бит
  передадутся в правильном порядке.
 /
void writeShiftRegister16(int ss_pin, uint16_t value)
{
  digitalWrite(ss_pin, LOW);
  / Фокус вот в чём: сначала шлём старший байт /
  SPI.transfer(highByte(value));
  / А потом младший /
  SPI.transfer(lowByte(value));
  digitalWrite(ss_pin, HIGH);
}

/ Слегка изменим функцию для работы с 16-битными значениями /
void rotateLeft(uint16_t &bits)
{
  uint16_t high_bit = bits & (1 << 15) ? 1 : 0;
  bits = (bits << 1) | high_bit;
}


void setup() {
 
  pinMode(col_1, OUTPUT);
  pinMode(col_2, OUTPUT);
  pinMode(col_3, OUTPUT);
  pinMode(col_4, OUTPUT);
  pinMode(col_5, OUTPUT);
  pinMode(col_6, OUTPUT);
  pinMode(col_7, OUTPUT);
  
  digitalWrite(col_1, HIGH);
  digitalWrite(col_2, HIGH);
  digitalWrite(col_3, HIGH);
  digitalWrite(col_4, HIGH);
  digitalWrite(col_5, HIGH);
  digitalWrite(col_6, HIGH);
  digitalWrite(col_7, HIGH);
  SPI.begin();
  pinMode(REG, OUTPUT);
  writeShiftRegister16(REG, 0);
}

// the loop routine runs over and over again forever:
void loop() {
  
   uint16_t nomad = 1;
   for(int i = 0; i < 10; i++){ // в данный момент матрица на 10 столбиков!      
   
//   writeShiftRegister16(REG, 0);
   
//   digitalWrite(col_1, HIGH);
//   delay(300);
//   digitalWrite(col_1, LOW);
//   writeShiftRegister16(REG, 0);
//   delay(300);
//   digitalWrite(col_2, HIGH);
//   delay(300);
//   digitalWrite(col_2, LOW);
//   writeShiftRegister16(REG, 0);
//   delay(300);
   
   writeShiftRegister16(REG, nomad);
   rotateLeft(nomad);
    
    delay(250);
  }     
}

Миниатюры:

Нажмите на изображение для увеличения
Название: Схема.jpg
Просмотров: 882
Размер: 586.2 Кб
ID: 63956  
fivist вне форума   Ответить с цитированием

Меню пользователя fivist
Ответ



« Предыдущая тема | Следующая тема »


Ваши права в разделе

Вы не можете создавать новые темы

Вы не можете отвечать в темах

Вы не можете прикреплять вложения

Вы не можете редактировать свои сообщения


BB коды Вкл.

Смайлы Вкл.

[IMG] код Вкл.

HTML код Выкл.


Правила форума

Быстрый переход


Похожие темы


Часовой пояс GMT +4, время: 15:00.



Источник: http://kazus.ru/forums/showthread.php?t=107805


Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор

Кнопка старт стоп на инжектор