Ардуино - запись звука

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

Dimon456 зачем примерно)) можно точно))
Одинаковое ли количество тактов вне зависимости от результата преобразования?
такты от результата не зависят))
[uquote="olegue",url="/forum/viewtopic.php?p=4245866#p4245866"]в момент одновременной работы двух каналов значения

rsValue=(ADCL|ADCH<<8);

становятся неадекватными, уходят в минус, например, удваиваются, начинают "прогать", хотя когда 2й канал не занят оцифровкой звука показывает все правильно[/uquote]
в AVR (например ATmega8 и др.) есть интересное явление...
каналы ADC имеют паразитную внутреннюю связь между собой...

например:
допустим pin 0 у нас подключён к батарейки 3,3 вольта.
допустим pin 1 у нас висит в воздухе (никуда не подключён).

когда мы измеряем напряжение на pin 0 то получаем 3,3 вольта.
когда мы измеряем напряжение на pin 1 то получаем те же 3,3 вольта. !

как так ? pin 1 у нас висит в воздухе (никуда не подключён) !
а просто напряжение 3,3 вольта из pin 0 попадает на pin 1 через внутренние паразитные связи мультиплексора ADC...

входное сопротивление пинов ADC имеют высокое входное сопротивление (>1MOм).
поэтому выходное сопротивление источника напряжение должно быть низким.

а ещё в даташите написано чётко - все неиспользуемые пины МК должны быть подключены на массу))
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

roman.com писал(а):а ещё в даташите написано чётко - все неиспользуемые пины МК должны быть подключены на массу))
а вот это надо бы попробовать
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Martian писал(а):есть мнение, что кое-кто опять соврал:
да он много где соврал.

Мне вот интересно
Спойлер

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

ISR(TIMER2_COMPA_vect) {

  rsValue = ADCW;

  ADMUX = 0x41; // set ADC to read pin A0, ADLAR to 1 (right adjust)
  sbi(ADCSRA, ADSC); // start ADC sample
  while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready

  uint8_t temp = ADCW >> 2;

  ADMUX = 0x40; // set ADC to read pin A1, ADLAR to 1 (right adjust)
  sbi(ADCSRA, ADSC); // start ADC sample

  // строка лишняя
  //while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready

  recByteCount++; // increment sample counter
  bufByteCount++;
  if (bufByteCount == 64 && bufWrite == 0) {
    bufByteCount = 0;
    bufWrite = 1;
  } else if (bufByteCount == 64 & bufWrite == 1) {
    bufByteCount = 0;
    bufWrite = 0;
  }
  if (bufWrite == 0) {
    buf00[bufByteCount] = (temp);
  }
  if (bufWrite == 1) {
    buf01[bufByteCount] = (temp);
  }
}
Сколько я им тактов сэкономил?
Еще когда писал - чего ждем? Седьмого пришествия?
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

[uquote="Martian",url="/forum/viewtopic.php?p=4245915#p4245915"]Connecting unused pins directly to VCC or GND is not recommended, since this may
cause excessive currents if the pin is accidentally configured as an output.[/uquote]
по-русски:
поскольку это может привести к чрезмерным токам, если источник питания СЛУЧАЙНО настроен в качестве выходного...
:)))
что значит СЛУЧАЙНО ???
т.е. ваш МК делает не то что вы ему говорите... а потому что ваш МК сам так захотел ! )))
:)))
что вы за программисты такие... что ваш МК делает что то без вашего разрешения ! )))
это просто какой то пипец ! )))
:))) :))) :)))
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

olegue писал(а):а вот это надо бы попробовать
попробуй ещё добавить стабилизацию входа... как советует даташит.

ISR(TIMER2_COMPA_vect) {
ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 1 (right adjust)

delay_us(10); // стабилизация входа...

sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
rsValue=ADCW;
...

стабилизация входа нужна чтобы после переключения мультиплексора напряжение "устаканилось"... ))

в твоём случае (с учетом ограничениями таймера = 45 мкс) можно не ставить задержку delay_us(10), а сделать по другому...

ISR(TIMER2_COMPA_vect) {
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
rsValue=ADCW;


ADMUX = 0x41; // set ADC to read pin A1, ADLAR to 1 (right adjust)
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
recByteCount++; // increment sample counter
bufByteCount++;
if (bufByteCount == 64 && bufWrite == 0) {
bufByteCount = 0;
bufWrite = 1;
} else if (bufByteCount == 64 & bufWrite == 1) {
bufByteCount = 0;
bufWrite = 0;
}

if (bufWrite == 0) {
buf00[bufByteCount] = (ADCW>>2);
}
if (bufWrite == 1) {
buf01[bufByteCount] = (ADCW>>2);
}

ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 1 (right adjust)
}

в этом случае, при следующем прерывании таймера, мультиплексор уже окажется подключён к каналу 0.
а так как следующее прерывание таймера наступит через 45 мкс... то за это время напряжение на канале 0 уже "устаканится"... ))
:tea:

стабилизация входа... нужна только при точных измерениях.
при записи звука точность не требуется.
:tea:

Добавлено after 32 minutes 21 second:
а тут что ты делаешь ?

////////////// НАЧИНАЕМ С ОБРАБОТКИ ВХОДА А0 ////////////////////////

// Каждые 100 мс мы накапливаем значения (для усреднения)
if (timerRSon==0){ // запустим таймер для отображения часов
timerRS=millis(); // включим миллис
timerRSon=1;

}
if (timerRSon==1){
if (millis()-timerRS>50)
{
////////////

//rsValue=analogRead(A0);


lcd.setCursor(0,0);
///sprintf(buffer, "Pow:%05i",rsValue);
///lcd.print(buffer);

/////////////
SrV=SrV+rsValue;
timerRSon=0;
}
}
// Каждые 1000 мс мы отображаем усредненное значение
if (timerLCLon==0){ // запустим таймер для отображения часов
timerLCL=millis(); // включим миллис
timerLCLon=1;
}
if (timerLCLon==1){
if (millis()-timerLCL>1000)
{
//lcd.setCursor(0,0);

SrVmid=SrV/20;
if (SrVmid<125) SrVmid=125; // меньше 125 - это 0%
procSrV=((SrVmid-125)*100)/194; //в % макс -318(320), мин 125, 320-125=195
sprintf(buffer, "Power:%04i (%02i)",SrV/20,procSrV);
lcd.print(buffer);
//Show_time();
timerLCLon=0;

SrV=0;
///////////////////////
}
}

как ты подключаешь батарейку ? где схема ?
и зачем накапливаем ? и зачем усреднения ?
:roll:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

roman.com, здесь я придумал 2 таймера

вот первый - каждый 50мс запускаем преобразование АЦП
и накапливаем их в переменной

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

// Каждые 50 мс мы накапливаем значения (для усреднения)
if (timerRSon==0){
timerRS=millis(); 
timerRSon=1;

}
if (timerRSon==1){
if (millis()-timerRS>50)
{

rsValue=analogRead(A0);
SrV=SrV+rsValue;

timerRSon=0;
}

вот второй, следует за первым по коду
этот цикл каждый 1000мс

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

// Каждые 1000 мс мы отображаем усредненное значение
if (timerLCLon==0){ 
timerLCL=millis(); 
timerLCLon=1;
}
if (timerLCLon==1){
if (millis()-timerLCL>1000)
{
lcd.setCursor(0,0);
SrVmid=SrV/20;   /// Когда попали сюда уже накопили 20 значений поэому делим на 20
if (SrVmid<125) SrVmid=125; // меньше 125 - это 0%
procSrV=((SrVmid-125)*100)/194; //в % макс -318(320), мин 125, 320-125=195

sprintf(buffer, "Power:%04i (%02i)",SrV/20,procSrV);
lcd.print(buffer);

timerLCLon=0;
SrV=0;

}
}

в цифоровых вольтметрах делают тоже самое , но как-то по другом. Но я не нашел готовый год поэтому решил поупражняться с millis()

Добавлено after 2 minutes 39 seconds:
Измеряемое напряжение несколько нестабильно , ну скажем 0.116-0.123. Меня устроит стабильное показание усредненной величины.


ну это я делал на analogRead, а потом уже начал делать чисто на регистрах и на таймере , который цифрует звук.
Реклама
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

olegue писал(а):Измеряемое напряжение несколько нестабильно , ну скажем 0.116-0.123. Меня устроит стабильное показание усредненной величины.
выше кидал кусок кода с фильтром для стабильного показания напряжения...
фильтр - это программная триггер-защелка... для устранения шума квантования ADC...

//объявляем переменные...
int a;
int u, ub;

//измеряем ADC...
adc(7);

//результат ADC фильтруем...
a=ADCW/2;
if (a>ub+1) {u=a/2; ub=a;};
if (a<ub-1) {u=a/2; ub=a;};

//отфильтрованный результат в переменной u

в троём коде будет так:

unsigned int a = 0;
unsigned int u = 0;
unsigned int ub = 0;

ISR(TIMER2_COMPA_vect) {
ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 1 (right adjust)
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready

//результат ADC фильтруем...
a=ADCW/2;
if (a>ub+1) {u=a/2; ub=a;};
if (a<ub-1) {u=a/2; ub=a;};
rsValue=u;
...
...
...

усреднения не нужны))
:tea:

а у тебя есть индикатор уровня записи ? ))

а можно вообще... сделать аудио редактор ))
диктофон.jpg
(48.58 КБ) 59 скачиваний
:)
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Какой упрямый человек.
У тебя АЦП работает на запредельных частотах, да еще и между каналами прыгает, там одного только шума квантования будет предостаточно, из 8 то бит бит 5 будет так хорошо.
Ведь показал самый быстрый код усреднения.
Накапливаешь в переменную примерно за 0,4 секунды 8192 измерения и сдвигаешь на 13 бит. Ты где был когда эту тему проходили здесь?

Ты когда на флешку собираешься писать? Тебе каждый такт важен, чем меньше тактов в прерывании тем лучше.
Ты, наверное, запамятовал, что у тебя еще один таймер каждые 1мс долбится, отбирая твои драгоценные такты, которые на вес золота.

В результате со всеми вытекающими последствиями.

Усе. Точка на этом.
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

нет... не всё))

все эти ваши усреднения... до фени ! показания как прыгали так и будут прыгать))
лучше выкинуть таймер с дуратскими усреднениями... и отдать такты фильтру...

где ты был когда мы это всё подробно разбирали...
:tea:
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

ХОрошо, а вот кто нить заметил, что я свой таймер вызываю раз в 50мс и там проходит оцифровка напряжения. А если я в таймер 22кгц ставлю это преобразование то оно будет сильно часто вызывать а в этом нет никакой нужды Прокомментируейт пож!
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

да
задумка была не загружать МК вторым преобразованием
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

olegue писал(а):задумка была не загружать МК вторым преобразованием
ну и не запускай каждое прерывание второй преобразование...
запускай 1 раз из 1000 )) остальное время потрать на другое...

лучше закинь всё протеус и посмотри как всё работает...
ILI9341-ардуино.jpg
(145.77 КБ) 56 скачиваний
сколько времени занимает одно преобразование ADC мы выяснили))

сколько времени занимает обработка данных и запись в буфер ADC мы выяснили выше))
ADC_bufer.jpg
(92.71 КБ) 54 скачивания
сколько времени занимает запись буфера на флешку в моём случае... мы выяснили выше))
ADC_SPI_поток.jpg
(108.16 КБ) 62 скачивания
почему надо два буфера а не один... тоже выяснили выше))
SPI_0.jpg
(94.14 КБ) 57 скачиваний
и т.д.

осталось всё собрать в единую картину))

как работают мои схемы... по времени... я знаю.
тайминги.jpg
(150.85 КБ) 68 скачиваний
как работает твои библиотеки... по времени... я НЕ знаю.
:tea:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

roman.com писал(а):и отдать такты фильтру...
Если усреднение не справится, то фильтр тем более.
У тебя АЦП работает на запредельных частотах, фильтр подрежет динамический диапазон сигнала, сверху и снизу. Можешь зарезать по самое самое и чисто середину оставить. В путь.
Martian писал(а):Однако, мне не верится, что этот мк не способен справиться.
Ну по чему не способен, 500кГц это еще не 1МГц, в тестах 1МГц выжимали на два канала.

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

roman.com, ты бы хоть синхронизировал таймер с АЦП, а то, while (bit_is_set(ADCSRA, ADSC)), ждешь седьмого пришествия.
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

Dimon456 писал(а):Если усреднение не справится, то фильтр тем более.
фильтр справится.

обязательно всё синхронизируем когда выкинем ардуину и будем писать по нормальному))
среду разработки ардуины я удалил... я этим больше не пользуюсь.
у меня есть всё... кроме ардуины))
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

roman.com писал(а):обязательно всё синхронизируем когда выкинем ардуину
Плохому танцору вечно что-то мешает.
Кстати ардуино это avr-gcc.
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4246226#p4246226"]Осталось мой код на реальном устройстве проверить. Но и поиграться с оптимизацией кода, в основном в прерывании.

roman.com, ты бы хоть синхронизировал таймер с АЦП, а то, while (bit_is_set(ADCSRA, ADSC)), ждешь седьмого пришествия.[/uquote]

вАш код:
Спойлер

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

volatile uint8_t sum_adc;
volatile bool n0=0, n1=0;
byte buf00[256]; // buffer array 1
byte buf01[256]; // buffer array 2

// ADC interrupt service routine
ISR(ADC_vect)
{
static uint8_t count = 0;
static uint8_t temp=0;
static uint32_t temp_adc=0;
static uint16_t count_buf = 0;

  if(ADMUX & (1<<MUX0)){
    temp = ADCH;   
    if(count_buf < 256) {
    buf00[count_buf] = temp;
    } else buf01[count_buf - 256] = temp;

    if(count_buf == 255) {
      n0=0; n1=1;
    }
     
    if(++count_buf > 511) {
      count_buf=0; n0=1; n1=0;
    }
    ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0
  }else{
    temp_adc += ADCH;

  if (++count > ((127)))  {
    count = 0;
    sum_adc = temp_adc>>7;
    temp_adc=0;
  }

    ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
  }

}


void loop() {
   if (n0==0 && n1 == 1) {
      rec.write(buf00, 256);  // save buf01 to card
      n0=0; n1=0;
    }
    if (n0==1 && n1 == 0) {
      rec.write(buf01, 256);  // save buf02 to card
      n0=0; n1=0;
    }
}

void StartRec() { // begin recording process

  digitalWrite(ledStart, HIGH);
  digitalWrite(ledStop, LOW);
  recByteCount = 0;
  recByteSaved = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  ADCSRA |= (1<<ADEN);
}

void StopRec() { // stop recording process, update WAV header, close file
  ADCSRA &= ~(1<<ADEN);
  writeOutHeader();
  digitalWrite(ledStart, LOW); // turn off recording LED
  digitalWrite(ledStop, HIGH); // light stop LED
  recPressed = 0;
}

void Setup_ADC() {
// ADC initialization
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);  // 500kHz
sampleRate = 19600; bytesPerSec = 19600;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // 250kHz
//sampleRate = 9800; bytesPerSec = 9800;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // 125kHz
//sampleRate = 4900; bytesPerSec = 4900;

ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}

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

Добавлено after 13 minutes 3 seconds:
ошибки:
Спойлер
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void __vector_21()':
DIMON456_AUDIORECORDER:27:13: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0
^~~~~~~~~~~~~
DIMON456_AUDIORECORDER:37:13: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
^~~~~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void loop()':
DIMON456_AUDIORECORDER:45:7: error: 'rec' was not declared in this scope
rec.write(buf00, 256); // save buf01 to card
^~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:45:7: note: suggested alternative: 'getc'
rec.write(buf00, 256); // save buf01 to card
^~~
getc
DIMON456_AUDIORECORDER:49:7: error: 'rec' was not declared in this scope
rec.write(buf01, 256); // save buf02 to card
^~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:49:7: note: suggested alternative: 'getc'
rec.write(buf01, 256); // save buf02 to card
^~~
getc
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void StartRec()':
DIMON456_AUDIORECORDER:56:16: error: 'ledStart' was not declared in this scope
digitalWrite(ledStart, HIGH);
^~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:56:16: note: suggested alternative: 'va_start'
digitalWrite(ledStart, HIGH);
^~~~~~~~
va_start
DIMON456_AUDIORECORDER:57:16: error: 'ledStop' was not declared in this scope
digitalWrite(ledStop, LOW);
^~~~~~~
DIMON456_AUDIORECORDER:58:3: error: 'recByteCount' was not declared in this scope
recByteCount = 0;
^~~~~~~~~~~~
DIMON456_AUDIORECORDER:59:3: error: 'recByteSaved' was not declared in this scope
recByteSaved = 0;
^~~~~~~~~~~~
DIMON456_AUDIORECORDER:60:3: error: 'recPressed' was not declared in this scope
recPressed = 1; // recording button has been pressed
^~~~~~~~~~
DIMON456_AUDIORECORDER:61:3: error: 'stopPressed' was not declared in this scope
stopPressed = 0;
^~~~~~~~~~~
DIMON456_AUDIORECORDER:62:3: error: 'writeWavHeader' was not declared in this scope
writeWavHeader();
^~~~~~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void StopRec()':
DIMON456_AUDIORECORDER:68:3: error: 'writeOutHeader' was not declared in this scope
writeOutHeader();
^~~~~~~~~~~~~~
DIMON456_AUDIORECORDER:69:16: error: 'ledStart' was not declared in this scope
digitalWrite(ledStart, LOW); // turn off recording LED
^~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:69:16: note: suggested alternative: 'va_start'
digitalWrite(ledStart, LOW); // turn off recording LED
^~~~~~~~
va_start
DIMON456_AUDIORECORDER:70:16: error: 'ledStop' was not declared in this scope
digitalWrite(ledStop, HIGH); // light stop LED
^~~~~~~
DIMON456_AUDIORECORDER:71:3: error: 'recPressed' was not declared in this scope
recPressed = 0;
^~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void Setup_ADC()':
DIMON456_AUDIORECORDER:77:20: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
^~~~~~~~~~~~~
DIMON456_AUDIORECORDER:79:1: error: 'sampleRate' was not declared in this scope
sampleRate = 19600; bytesPerSec = 19600;
^~~~~~~~~~
DIMON456_AUDIORECORDER:79:21: error: 'bytesPerSec' was not declared in this scope
sampleRate = 19600; bytesPerSec = 19600;
^~~~~~~~~~~
exit status 1
'ADC_VREF_TYPE' was not declared in this scope
Добавлено after 3 minutes 1 second:
Тут если на то пошло, надо определить какие процедуры заменить в моем коде и какие переменные исключить/добавить.
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

[uquote="olegue",url="/forum/viewtopic.php?p=4246306#p4246306"]я бы его проверил,но так как он мне не совсем понятен[/uquote]
тут даже мне не понятен... а ардуине и подавно))
:))
начиная на ещё стадии инициализации ADC...

void Setup_ADC() {
// ADC initialization
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0); // 500kHz
sampleRate = 19600; bytesPerSec = 19600;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // 250kHz
//sampleRate = 9800; bytesPerSec = 9800;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // 125kHz
//sampleRate = 4900; bytesPerSec = 4900;

ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}

во первых есть стандартные настройки sampleRate = 8000,11025,16000,22050,44100
нафига делать не стандартные... не ясно)) наверное чтобы невозможно было послушать на обычном плеере))
:tea:
во вторых зачем вот это
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
почему не записать просто
ADCSRA=0x6D;
:tea:
в третьих... нафига писать регистры которые и так сброшены в 0
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
в четвёртых... этот код будет работать только на ардуине c AVR типа ATmega328
а если я захочу этот код запустить на ардуине c AVR типа ATmega8 то нифига работать не будет)) потому что в ардуине c AVR типа ATmega8 нет регистров DIDR0 и ADCSRB... ))
:tea:
в пятых... это для AVR типа ATmega328
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
а для ATmega8 надо писать так
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
а почему тогда прост оне записать так
ADCSRA=0x6D;
и для AVR типа ATmega328 и для AVR типа ATmega8
:tea:
в шестых...
давайте проверим это в простом компиляторе AVR...
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
компилятор ответил - ОШИБКА !
ошибка_компилятор_AVR.jpg
(83.32 КБ) 64 скачивания
мой компилятор не знает что такое ADEN, ADSC, ADFR, ADIF, ADIE, ADPS2, ADPS1, ADPS0... и т.д.))

а теперь давайте запишем по нормальному))
ADCSRA=0x6D;
компилятор_OK.jpg
(110.09 КБ) 54 скачивания
компилятор ответил - OK
:tea:
вывод:
надо писать так
ADCSRA=0x6D;
или так
ADCSRA=0b01101101;
тогда будет всё работать хорошо)) и любая ардуина (на ATmega328 и на ATmega8) и любой компилятор ))
оно и понятно... эта простая логическая операция записи значения 0x6D в регистр ADCSRA понятна всем))
:tea:
в седьмых...
в восьмых...
:))
блин... мы ещё даже не начали разбирать код... а у нас уже куча ошибок повыскакивало...
что же будет дальше... страшно представить))
:)
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

Немного вьехал в эту тему и понял, что вот МК один а люди понимают его по разному.

Ладно, я вот хочу эту тему с двумя преобразованиями слегка поставить на паузу. Мне кажет мне самому надо чуток добрать знаний и поразбиратсяя как и что делать. Особенно я вот вижу прогресс когда сам смотрню регистры пример и понимаю что делаю.

Но кроме этого, я еще одну фишку хочу добавить в этот проект.

У меня есть 4х битный сигнал, я хочу подать его на свободные пины Ардуины(ну считай Атмеги) и преобразовать его в десятичное число
4х битный сигнал - 4 пина будут взяты с hc595 c пинов 15,1,2,3. Дело осложняется еще и тем, что 595 запитана от 3.3 в, а Ардуина запитана от 5в.
Я полагаю , что уровнь "еденица" с 595 идет высокий. Какая помощь мне нужна?
1. Настройка пинов
2. Формула преобразования в bcd to decimal

Буду весьма признателен за участие всех кто мне здеьс помогает.

Добавлено after 6 minutes 58 seconds:
ну и с уровнями что делать? непонятно!
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

если источник имеет меньшее напряжение, а приемник большее - входы приемника ставь в z состояние и соединяй напрямую (если страшно - добавь в разрыв резисторы 300-500 Ом).

бсд 4 бита соответствует хексу - преобразовывать ничего не надо.
бсд 8 бит в хекс: у=х&0х0f+(x>>4)*10;
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

4х битный сигнал напряжением 3.3 от hc595 подключаются НАПРЯМУЮ к Атмеги (ну считай Ардуины).
для этого никакие резисторы не нужны))

Настройка пинов - пины Атмеги (ну считай Ардуины) должны настроены на вход.

Формула преобразования в bcd to decimal ?

у=х&0х0f+(x>>4)*10;

боюсь что эта формула работать не будет))
хотя тут всё зависит от компилятора... что он первым будет делать... х&0х0f или (x>>4)*10
))
но жаде если компилятор всё сделает правильно... то все равно работаь не будет ))
Последний раз редактировалось roman.com Чт июн 16, 2022 17:07:24, всего редактировалось 1 раз.
Ответить

Вернуться в «AVR»