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

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

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

Martian писал(а):...
этот бред даже читать не хочу... :)))
olegue писал(а):То что счас находится на флэшке врядли удастся втюхать самому лопоухому врагу даже в базарный день.
ну не хочешь "шифровальщик"... сделай "копировальщик" ))
:))
берём ДВЕ флешки... подключаем к AVR... нажимаем кнопочку "копировать"...

AVR читает сектора... начиная с нулевого и до последнего... ))

11111111
22222222
33333333
...

затем всё копирует на вторую флешку...

11111111
22222222
33333333
...
:tea:
фактически мы копируем ОБРАЗ флешки...

Это помнишь... как раньше была популярная программа... копирования пиратских DVD ))
nero.jpg
(60.8 КБ) 42 скачивания
AVR так тоже умеет... копировать ОБРАЗ флешки))
а можно копировать ОБРАЗ флешки на ПК... или ещё куда)) для AVR не важно...

зачем ?
а вдруг у нас важные данные на флешке... а флешка сломается/потеряется... и всё... :cry:
olegue писал(а):пока мои знания в СИ на уровне где-то что-то подкрутить в готовом коде , да и то не всегда, как видилте.
ну... уже хорошо)) надо больше СИ )) чем больше СИ тем лучше ))

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

Сообщение olegue »

roman.com, согласен, а я вот такой вариан переноса информации пока не рассматривал. Надо подумать.Возможно здесь буедт какая-то прикладная суть.

Но я вернутсь к своим баранам

В моем диктофоне, записи звука происходит с помощью "ручной" настройки регистров.
Если я задействую еще один аналоговый вход уже коммандой AnalogRead(pin4) на собьются ли настройки того первого аналогово входа с которого я пишу звук?
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

roman.com писал(а):а вдруг у нас важные данные на флешке... а флешка сломается/потеряется... и всё... :cry:
Это же нужно физическое соединение меги с пк? Не проще тогда флешку в пк вставить, и копируй куда угодно.
roman.com писал(а):берём ДВЕ флешки... подключаем к AVR... нажимаем кнопочку "копировать"...
Бред, полный.
roman.com писал(а):AVR читает сектора... начиная с нулевого и до последнего... ))
roman.com писал(а):затем всё копирует на вторую флешку...
Особенно это. Это нужна точно такая же флешка, да же без битых секторов.

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

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

Dimon456 писал(а):Это же нужно физическое соединение меги с пк? Не проще тогда флешку в пк вставить, и копируй куда угодно.
ты форум вообще не читаешь))
[uquote="olegue",url="/forum/viewtopic.php?p=4242807#p4242807"]есть задумка перенести это все на esp8266, там готовый wifi есть[/uquote]
olegue писал(а):привлекает wifi модуль... что бы флэшку не дергать из устройства
[uquote="olegue",url="/forum/viewtopic.php?p=4242778#p4242778"]ПК меня интересует только в контексте передачи готовых файлов по Wifi на ftp сервер. Или через sim800 сразу в WEB...[/uquote]
круто !))
нафиг те флешки))
а давайте писать сразу в ОБЛАКО ))
:))
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Martian писал(а):я ожидал возможности работы с прерываниями, ардуина не способна генерировать прерывание по завершению преобразования AЦП?
мега328 способна генерировать прерывание по завершению преобразования AЦП, я к этому и подводил, скрестить АЦП и запись на карту, но, к сожелению, выше все померили, измерили, и сделали соответствующий вывод
roman.com писал(а):круто !))
нафиг те флешки))
а давайте писать сразу в ОБЛАКО ))
Реклама
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

диктофоны... флешки... они никому не нужны))

надо сразу делать IP камеры... с Интернетом...
ip.jpg
(31.9 КБ) 64 скачивания
хоть какая то польза будет ))
:tea:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="Martian",url="/forum/viewtopic.php?p=4243600#p4243600"][uquote="olegue",url="/forum/viewtopic.php?p=4243399#p4243399"]Если я задействую еще один аналоговый вход уже командой AnalogRead(pin4) на собьются ли настройки того первого аналогово входа с которого я пишу звук?[/uquote]
Нет, команда просто выполняет коммутацию каналов и запускает обработку АЦП, судя по исходникам: https://forum.arduino.cc/t/arduino-sour ... c/229752/4
н-да... я ожидал возможности работы с прерываниями, ардуина не способна генерировать прерывание по завершению преобразования AЦП?[/uquote]

ну собственно случилось то что я и предполагал, при добавлении еще одого канал получения сигнала analogRead(A0) считывание с А0 происходит прекрасно, файл на флэшку якобы пишется и имеет размер ,но звука в нем нет!!!!

Такие дела...

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

Сообщение olegue »

сбиваются настройки регистров. Вопрос какие?

Добавлено after 1 minute 32 seconds:
analogRead - это 10 битная обработка с разрешение 1024, а вот звук насколько я понимаю у нас 8ми битный. Ну это так, рассуждения дилетанта.

Добавлено after 2 minutes 12 seconds:
Спойлер

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

/* Dmitry OSIPOV. http://www.youtube.com/user/d36073?feature=watch
  Arduino Audio Recorder V.1-20160524.
  ----------------------------------------------------
   Arduino Projects: Digital Audio Recorder.
  http://apcmag.com/arduino-projects-digital-audio-recorder.htm/
  ----------------------------------------------------
  SD-карту лучше класс 10 и выше.
  Питание от батареи или аккумулятора.
  Микрофон подключить к pin (A5).
  ----------------------------------------------------
  Download - sketch "Arduino Audio Recorder V.1-20160524"
  Библиотеку - SdFat.
  Фото.
  https://yadi.sk/d/zqi8-L5xruhFq
  + sketch оставлю в комментарии - под видео.
  ----------------------------------------------------
*/
#include <LiquidCrystal_I2C.h>
#include <SdFat.h> // https://yadi.sk/d/zqi8-L5xruhFq
//#include <EEPROM.h>

#include <RTClib.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

SdFat sd;
SdFile rec;
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
const int chipSelect = 4; /* Поменял на 10-pln */
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;
unsigned long sampleRate = 22050;
unsigned long bytesPerSec = 22050;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
const int btnStart = 6;
const int btnStop = 5;
const int ledStart = 2;
const int ledStop = 3;
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[64]; // buffer array 1
byte buf01[64]; // buffer array 2
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;

unsigned long timer1;
int timer1on = 0;
//----------------------------------------------------
//char NameRecord[4]; /* Имя нового - записываемого файла на SD-карту. */
//int RecordNumber; /* Номер записи - храним в EEPROM. в диапазоне 0..255. */
//char filename[12]; 

char filename[22];
char foldername[10];

unsigned long timerLCL;
int timerLCLon=0;

int rValue=0;

char buffer[16] ;
void setup() { // THIS RUNS ONCE
//
  lcd.init();
   lcd.backlight();
  //lcd.setCursor(3,0);
  //lcd.print("Hello, world!");
 

//
  
  rtc.begin();
//EEPROM.put(0, 20000);
  Setup_timer2();
  Setup_ADC();

  pinMode(10, OUTPUT);
  pinMode(ledStart, OUTPUT);
  pinMode(ledStop, OUTPUT);
  pinMode(btnStop, INPUT_PULLUP);
  pinMode(btnStart, INPUT_PULLUP);

  if (sd.begin(chipSelect, SPI_FULL_SPEED)) { // initialise card on SPI to 8MHz SPI bus speed
    for (int dloop = 0; dloop < 4; dloop++) {
      digitalWrite(ledStart, !digitalRead(ledStart));
      delay(100);
    }
  } else { 
      lcd.setCursor(0,1);
      lcd.print("SD Card not found");
    // if error, flash LED twice per second, until reset
    while (1) {
      digitalWrite(ledStart, !digitalRead(ledStart));
      delay(500);
    }
  }

}

void loop() { // THIS RUNS LOTS!

 if (timerLCLon==0){   // запустим таймер для отображения часов
  timerLCL=millis();  // включим миллис
  timerLCLon=1;
 }
 if (timerLCLon==1){
  if (millis()-timerLCL>500)
    {
      rValue=analogRead(A0);
      lcd.setCursor(0,0);
      
      sprintf(buffer, "Power:%04i",rValue); 
      lcd.print(buffer);
      
      ///////////////////////
      DateTime now = rtc.now();
      lcd.setCursor(1, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");     
      lcd.print(now.second());
      timerLCLon=0;  }
 }
 if (digitalRead(btnStart) == LOW && recPressed == 0) {
    
    DateTime now = rtc.now();
    String strFile,strFolder;  //declaring string.
    strFolder=String(now.timestamp(DateTime::TIMESTAMP_DATE));
    strFolder.replace("-", "");
    strFolder.toCharArray(foldername, sizeof(foldername));
    sd.mkdir(foldername);  // Создаю директорию - пробовал без этого - никак
    strFolder.concat("/");
    strFile=String(now.timestamp(DateTime::TIMESTAMP_TIME));
    strFile.replace(":", "-");
    strFile.concat(".wav");
    strFolder.concat(strFile);
    strFolder.toCharArray(filename, sizeof(filename));
    
    StartRec(); // launch StartRec method
    timer1on = 0;
  }
  else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 0)
    {
      timer1 = millis();
      timer1on = 1;
    }
    else if (digitalRead(btnStart) == LOW && recPressed == 1 && timer1on == 1) {
    timer1on = 0; 
    }
   
  else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 1 && (millis() - timer1) > 2000)
  {
    StopRec(); // launch StopRec method
    
    /*         Поэтому (Делаем программную перезагрузку). */
    ((void (*)())0x0000)(); /* Делаем программную перезагрузку - Arduino */
  }
 
  if (recByteCount % 128 == 64 && recPressed == 1) {
    rec.write(buf00, 64);  // save buf01 to card
    recByteSaved += 64;
  }
  if (recByteCount % 128 == 0 && recPressed == 1) {
    rec.write(buf01, 64);  // save buf02 to card
    recByteSaved += 64;
  }
}

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();
  sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio

}

void StopRec() { // stop recording process, update WAV header, close file

  cbi (TIMSK2, OCIE2A); // disable timer interrupt
  writeOutHeader();
  digitalWrite(ledStart, LOW); // turn off recording LED
  digitalWrite(ledStop, HIGH); // light stop LED
  recPressed = 0;

}

void writeOutHeader() { // update WAV header with final filesize/datasize

  rec.seekSet(4);
  byte1 = recByteSaved & 0xff;
  byte2 = (recByteSaved >> 8) & 0xff;
  byte3 = (recByteSaved >> 16) & 0xff;
  byte4 = (recByteSaved >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.seekSet(40);
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.close();

}

void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = rtc.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

void writeWavHeader() { // write out original WAV header to file

  recByteSaved = 0;
  
   SdFile::dateTimeCallback(dateTime);
   ////
  
   ////
   rec.open(filename, O_CREAT | O_TRUNC | O_RDWR); /* Имя нового - записываемого файла на SD-карту. */
   
  rec.write("RIFF");
  byte1 = fileSize & 0xff;
  byte2 = (fileSize >> 8) & 0xff;
  byte3 = (fileSize >> 16) & 0xff;
  byte4 = (fileSize >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.write("WAVE");
  rec.write("fmt ");
  byte1 = waveChunk & 0xff;
  byte2 = (waveChunk >> 8) & 0xff;
  byte3 = (waveChunk >> 16) & 0xff;
  byte4 = (waveChunk >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = waveType & 0xff;
  byte2 = (waveType >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = numChannels & 0xff;
  byte2 = (numChannels >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = sampleRate & 0xff;
  byte2 = (sampleRate >> 8) & 0xff;
  byte3 = (sampleRate >> 16) & 0xff;
  byte4 = (sampleRate >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = bytesPerSec & 0xff;
  byte2 = (bytesPerSec >> 8) & 0xff;
  byte3 = (bytesPerSec >> 16) & 0xff;
  byte4 = (bytesPerSec >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = blockAlign & 0xff;
  byte2 = (blockAlign >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = bitsPerSample & 0xff;
  byte2 = (bitsPerSample >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  rec.write("data");
  byte1 = dataSize & 0xff;
  byte2 = (dataSize >> 8) & 0xff;
  byte3 = (dataSize >> 16) & 0xff;
  byte4 = (dataSize >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);

}

void Setup_timer2() {

  TCCR2B = _BV(CS21);  // Timer2 Clock Prescaler to : 8
  TCCR2A = _BV(WGM21); // Interupt frequency  = 16MHz / (8 x 90 + 1) = 22191Hz
  OCR2A = 90; // Compare Match register set to 90

}

void Setup_ADC() {

  ADMUX = 0x61; // set ADC to read pin A5, ADLAR to 1 (left adjust)
  cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
  sbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);
}

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
  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] = ADCH;
  }
  if (bufWrite == 1) {
    buf01[bufByteCount] = ADCH;
  }


  //  if (recByteCount % 128 < 64) { // determine which buffer to store sample into
  //    buf01[recByteCount % 64] = ADCH;
  //  } else {
  //    buf02[recByteCount % 64 ] = ADCH;
  //  }

}
вот код, может кто посмотрит...

Добавлено after 10 minutes 24 seconds:
c форматами провозился может час... Вот ссылка как надо На LCL правильно вводить цифры.
https://arduino.ru/forum/programmirovan ... noi-stroke

Добавлено after 4 hours 39 minutes 28 seconds:
Не видать не будет этого. В паралельном проекте( там где используется библиотека TMRpsm.h написано в комментарии что не будет писать звук в Multi Mode. Я так понимаю что это режим использования несклькоих аналоговых входов одновременно. Не понимаю, конечно , в чем причина этого ограничения. Но вот удалось накопать такие мысли
в Setup() я задаю

SetupADC() где прописываю пин , ну типа ADMUX=0x61, т.е А1
А вот когда я в Loop() обращаюсь к пину А0, т.е пишут analogRead(A0), то больше к пину А1 я уже не возвращаюсь.

Вообще то вся работа по оцифровке , насколько я понимаю , происходит здеьс

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

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
  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] = ADCH;  }
  if (bufWrite == 1) {    buf01[bufByteCount] = ADCH;  }

}
может быть мне бы стоило задублировать здесь ADMUX =0x61 в начале?

Добавлено after 2 minutes 47 seconds:
Так получается , что алгоритме теряется пин с которого идет оцифровка после analogRead(A0).
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

Martian, запись вернулась! но analogRead(A0) сошел с ума.

может стоило бы весь

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

void Setup_ADC() {

  ADMUX = 0x61; // set ADC to read pin A5, ADLAR to 1 (left adjust)
  cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
  sbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);
}
туда всадить?

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

Сообщение olegue »

у меня тоже есть идея

если ставить ADMUX=0x61 то ADLAR=1

а в Ардуино по умолчанию
The ADLAR determines the presentation of the ADC conversion result. If it is 1, the ADC conversion result is left adjusted. If 0, right adjusted. It is set to 0, right adjusted, by the Arduino software.
Что если я при сэмплировании тоже перейду на ADLAR=0. И тоггда не будет конфликта!
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

byte ah = ADCH; //здесь берём данные из ADCH
byte al = ADCL; //и ADCL, далее работаем только c ahи al
тока раньше я работал с готовым числом int

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

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

сделай две процедуры АЦП подряд (те, что у тебя были изначально), но между ними впиши в адмукс значение для второго канала (скорее всего 0х60) и подожди 10мкс (вроде так по д.ш., уточню только завтра), после 2й процедуры оцифровки снова запиши в адмукс значение для первого канала (0х61)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

olegue писал(а):Так получается , что алгоритме теряется пин с которого идет оцифровка после analogRead(A0).
опять всё по новой...))

да напиши ты уже нормальную функцию ADC...

void adc(unsigned char adc_input)
{
ADMUX = 0b01000000 | adc_input; // опорное AVCC // канал ADC0...ADC7
delay_us(10); // стабилизация входа...
ADCSRA|=0b01000000; // Старт преобразования.
while (ADCSRA & 0b01000000); // При завершении преобразования этот бит сбрасывается аппаратно.
}

и вызывай её сколько хочешь раз)) с указанием номера канала...

а то ты так будешь но Нового Года сидеть))
:tea:
adc(0); // канал 0
...
adc(1); // канал 1
...
adc(2); // канал 2
...
и т.д.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

roman.com писал(а):while (ADCSRA & 0b01000000);
Шикарный план.
Martian писал(а):Нормально - это написать обработчик прерывания АЦП
Я еще на какой странице про это торочил.
Ну нет у меня на этом компе протеуса, что бы проверить с какой скоростью идет семплирование, и ни кто здесь про это не сказал. При последовательной оцифровке двух каналов скорость семплирования в два раза упадет.

olegue, за чем тебе второй канал, куда ты его собрался использовать? Писать во второй файл на карту?
Имей ввиду этот драйвер, на верное, я не смотрел код, не поддерживает работу с двумя открытыми файлами.
Ты так и не ответил на вопрос, рушит ли он файловую систему на карте?
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

результат не возвращает.... чтобы не тратить впустую процессорное время.
результат преобразования содержится в регистрах...
даташит.jpg
(48.64 КБ) 75 скачиваний
но так как тут даташиты никто не читает... поэтому одни и те же вопросы повторяются п округу))
:tea:
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

кроме вас никто доступа к регистрам не имеет...

в каком случае мы можем застрять в цикле while (ADCSRA & 0b01000000); ?

ADC в AVR соран на простой тупой логике))

в каком случае может зависнуть простая тупая логика ?
я даже себе представить такие случаи не могу... даже чисто гипотетически))

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

Добавлено after 2 minutes 1 second:
а запускать непрерывное преобразование и потом ловить результаты в прерываниях по окончанию преобразования - это пустая трата времени... и процессорного... и вашего))
Друг Кота
Сообщения: 9595
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

Martian писал(а):Я не знаю устройство...
в этом вся проблема))
I2C я не использую...
Martian писал(а):Наверняка в атмеге есть правила их чтения и какие-то блокировки.
откуда в avr БЛОКИРОВКИ РЕГИСТРОВ ??? :))
Martian писал(а):сторожевой таймер (который ещё надо включить, настроить, написать пост-обработку события) - круто.
//Ст таймер тактируется от отдельного встроенного генератора частотой 1 МГц.
//Ст таймер сбрасывается при выключении или во время сброса микроконтроллера.
//WDTCR=0b00001111; // настройка сторожевого таймера:
//0... .... - Зарезервированные
//.0.. .... - Зарезервированные
//..0. .... - Зарезервированные
//...1 .... WDCE - Разрешение изменения сторожевого таймера
//.... 1... WDE - Вкл. сторожевого таймера
//.... .1.. WDP2 - предделитель
//.... ..1. WDP1 - предделитель
//.... ...1 WDP0 - предделитель
////////////////////////////////////////////////////////////////////////////////
//предделитель WDP2 -WDP1 -WDP0:
// 000: количество тактов: 16,384; время переполнения: 16,3 mc
// 001: количество тактов: 32,768; время переполнения: 32,5 mc
// 010: количество тактов: 65,536; время переполнения: 65 mc
// 011: количество тактов: 131,072; время переполнения: 0,13 c
// 100: количество тактов: 262,144; время переполнения: 0,26 c
// 101: количество тактов: 524,288; время переполнения: 0,52 c
// 110: количество тактов: 1.048,576; время переполнения: 1,0 c
// 111: количество тактов: 2.097,152; время переполнения: 2,1 c
////////////////////////////////////////////////////////////////////////////////
//Вкл. ст таймер:
WDTCR=0b00011000; // Разрешение изменения сторожевого таймера
WDTCR=0b00001000; // Вкл. ст таймер
// #asm("wdr") // Сброс сторожевого таймера
////////////////////////////////////////////////////////////////////////////////
//Выкл. ст таймер:
//WDTCR=0b00011000; // Разрешение изменения сторожевого таймера
//WDTCR=0b00000000; // Выкл. ст таймер

настроить ОДИН регистр - это просто безумно сложная задача !))
не вздумайте повторять это дома !
:))
Martian писал(а):написать пост-обработку события
:o
откуда в avr ОБРАБОТЧИК СОБЫТИЙ ??? :))

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

Сообщение olegue »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4244700#p4244700"]
roman.com писал(а):while (ADCSRA & 0b01000000);
Шикарный план.
Martian писал(а):Нормально - это написать обработчик прерывания АЦП
Я еще на какой странице про это торочил.
Ну нет у меня на этом компе протеуса, что бы проверить с какой скоростью идет семплирование, и ни кто здесь про это не сказал. При последовательной оцифровке двух каналов скорость семплирования в два раза упадет.

olegue, за чем тебе второй канал, куда ты его собрался использовать? Писать во второй файл на карту?
Имей ввиду этот драйвер, на верное, я не смотрел код, не поддерживает работу с двумя открытыми файлами.
Ты так и не ответил на вопрос, рушит ли он файловую систему на карте?[/uquote]


1.Если скорость упадет до величины когда звук станет неприемлиым, то такое конечно , меня не устраивает. Например , я сделал вывод часов на экран 1602 и уже получил артефакты при записи. Данные со второго канала я планировал выводить на экран, ну и писать файл.

2.Да, я хотел писать еще один файл,одновременно со звуком.

3.Я не пробовал открывать второй файл, хотя конечно, надо было бы. (

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

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

Martian писал(а):Вам стоит почитать про атмегу?
мне не нужно читать про атмегу...

выше писал как надо читать регистры...
[uquote="roman.com",url="/forum/viewtopic.php?p=4242597#p4242597"]нормальные люди сначала пишут младшие регистры...
ADCL = 11111111
а када младшие регистры заполнятся... переносим разряды в старшие регистры...
ADCH = 00000011

при чтении процесс обратный...[/uquote]
регистры не блокируются))
а почему так происходит ? потому шина данных 8-ми битная.))
да потому что AVR 8-ми битный !!!
поэтому при чтении 16-битных регистров чтение происходит поочереди...
сначала читаем первый регистр... по умолчанию младший... после этого значение второго переносится в первый... по умолчанию старший... затем читаем второй регистр...
а если первым читать старший регистр... то значение младшего потеряем...
и т.д. и т.п.

только нафиг нужны кому такие подробности))
читаем сразу оба регистра... ADCW = 00000011 11111111

и не забиваем себе голову такими подробностями))
:tea:
[uquote="Martian",url="/forum/viewtopic.php?p=4244745#p4244745"]если программа не понимает, что была сброшена ватчдогом.[/uquote]
блин... нафига простому AVR знать чем он был сброшен))) это не Windows... с кодами ошибок)) :))
ну если очень надо... то пишите... если совсем заняться нечем)))

ещё исключения допишите...

try {...} catch (Exception){}

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

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

olegue что ты хочешь... не пойму))
писать два канала сразу ?
кто мешает ?)) делай "переключатель" каналов и пиши сразу два канала))


сделай две функции...

// включаем канал номер 0
void Setup_ADC_0() {

ADMUX = 0x60; // set ADC to read pin A5, ADLAR to 1 (left adjust)
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
}

// включаем канал номер 1
void Setup_ADC_1() {

ADMUX = 0x61; // set ADC to read pin A5, ADLAR to 1 (left adjust)
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
}


// в прерывании таймера переключаем каналы...

ISR(TIMER2_COMPA_vect) {

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) {
Setup_ADC_0(); // включаем канал номер 0
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
buf00[bufByteCount] = ADCH;
}

if (bufWrite == 1) {
Setup_ADC_1(); // включаем канал номер 1
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
buf01[bufByteCount] = ADCH;
}

}

:roll:
чёто намудрили с буферами)))
Ответить

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