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

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

Сообщение olegue »

Martian, Спасибо! Вроде все понятно, ну типа понятно что и куда всадить,а так ,конечно, темный лес. Буду пробовать вечерком.

вот например

if (bit_is_set(ADMUX,1)) // проверка 0х61

как тут происхоит проверка на 0x61, ADMUX это регистр у которого 8 бит , младшие (справа которые, я так понимаю) отвечают за порт с окторого идет оцифровка.
ну и далее тоже

cbi(ADMUX,1); //переключаем на другой канал

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

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

roman.com писал(а):// в прерывании таймера переключаем каналы...

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;
}

}
не)) не так
надо отдельную переменную для каналов... ))

char channels = 0; // номер канала

ISR(TIMER2_COMPA_vect) {

if (channels == 0) {Setup_ADC_0();}; // вкл канал номер 0
if (channels == 1) {Setup_ADC_1();}; // вкл канал номер 1
channels++;
if (channels == 2) {channels = 0;}; // вкл канал номер 0

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;
}

}
не... опять не так))
Последний раз редактировалось roman.com Пн июн 13, 2022 15:30:18, всего редактировалось 1 раз.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

Martian писал(а):olegue, если приведёте полный текущий исходник, который сейчас работает, то я могу попробовать переделать его
спрашиваете еще...., кто ж от такого откажется
Спойлер

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

/* 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;

unsigned long timerRS;
int timerRSon=0;

int SrV,rsValue, procSrV, SrVmid;

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!
////////////// НАЧИНАЕМ С ОБРАБОТКИ ВХОДА А0 ////////////////////////
  
// Каждые 100 мс мы накапливаем значения (для усреднения)
 if (timerRSon==0){   // запустим таймер для отображения часов
  timerRS=millis();  // включим миллис
  timerRSon=1;
  
 }
 if (timerRSon==1){
  if (millis()-timerRS>50)
    {
      //rsValue=analogRead(A0);
      SrV=SrV+rsValue; 
      timerRSon=0;
   }
 }
// Каждые 1000 мс мы отображаем усредненное значение
  if (timerLCLon==0){   // запустим таймер для отображения часов
  timerLCL=millis();  // включим миллис
  timerLCLon=1;
 }
 if (timerLCLon==1){
  if (millis()-timerLCL>500)
    {
      lcd.setCursor(0,0);
      
      SrVmid=SrV/10;
      if (SrVmid<125) SrVmid=125;    // меньше 125 - это 0%
      procSrV=((SrVmid-125)*100)/194;  //в % макс -318(320), мин 125, 320-125=195   
      sprintf(buffer, "Power:%03i (%02i)",SrV/10,procSrV); 
      lcd.print(buffer);
      //Show_time();
      timerLCLon=0;
      
      SrV=0;
      ///////////////////////
   }
 }

 ////////////// ЗДЕСЬ УЖЕ ОБРАБОТКА ВХОДА А1 ////////////////////////
 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 Show_time(){    
  DateTime now = rtc.now();
      lcd.setCursor(1, 1);
      lcd.print(now.hour());
      lcd.print(":");
      lcd.print(now.minute());
      lcd.print(":");     
      lcd.print(now.second());
       }

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;
  //  }

}

//rsValue=analogRead(A0); - закоментил пока

Добавлено after 19 minutes 8 seconds:
еще вот статью нашел интересную
analogRead() — прощай

https://www.drive2.ru/b/468551383692346485/

надо изучить.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Как все сложно
Спойлер

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

// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (1<<ADLAR))

volatile uint8_t sum_adc;

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

	if(ADMUX & (1<<MUX0)){
		temp = ADCH;		
		rec.write(temp, 1);  // save to card
		ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0 
	}else{
		temp_adc += ADCH;
		ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
	}

	if (++count > 127)  { 
		count = 0;
		sum_adc = temp_adc>>6; 
		temp=0; 
		temp_adc=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();
  //sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio
  
  ADCSRA |= (1<<ADEN);
}

void StopRec() { // stop recording process, update WAV header, close file
  //cbi (TIMSK2, OCIE2A); // disable timer interrupt

  ADCSRA &= ~(1<<ADEN);

  writeOutHeader();
  digitalWrite(ledStart, LOW); // turn off recording LED
  digitalWrite(ledStop, HIGH); // light stop LED
  recPressed = 0;
}

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() {  
// 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 = 20000; bytesPerSec = 20000;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);	// 250kHz
//sampleRate = 9803; bytesPerSec = 9803;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);	// 125kHz
//sampleRate = 4807; bytesPerSec = 4807;
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Martian писал(а):и не уверен, что вызов функций записи из прерывания ацп - хорошая идея.
Это по чему?
Еще ее и заинлайнить можно. Грубо говоря времени на один байт уйдет что-то около 10мкс.
Не нравится, так, с буферами сделайте.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

Martian,

Изображение

чет, я не понял, что ему надо!

ну и еще добавил перед setup()

char notsound;

Добавлено after 8 minutes 9 seconds:
дык нету функции в коде

_write()

Добавлено after 1 minute 50 seconds:
а так это попытка обявить функции в теле другой функуции?

дык тут такое не прокатывает

выношу ее и вызываю

Добавлено after 1 minute 55 seconds:
или не надо вызывать, там она вызывается несколько раз, может только вынести ?

Добавлено after 5 minutes 46 seconds:
Изображение

так пойдет или задумывалось по другому?
или убрать лишний вызов _write()

Добавлено after 5 minutes 17 seconds:
Ошибок компиляции нету, вкидываю в прошивку в МК. Буду смотреть че будет.

Добавлено after 6 minutes 44 seconds:
не пишет звук
пробую что-то записать- дает вот тайкой файл и светодиод (у меня красный-индикатор записи) - горит постоянно.

Изображение

Добавлено after 3 minutes 39 seconds:
вот код без ошибок компиляции
Вложения
audiorecorder_martian.arduino.txt
(11.1 КБ) 73 скачивания
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

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

Сообщение olegue »

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

Сообщение olegue »

неа, не работает , звук не пишет. Все тоже что и в прошлый раз. Красная (запись) горит постоятнно. А должна лишь когда запись идет.

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

Сообщение olegue »

неа, отладчиком это быстро не будет, в арудине отладчика нету. Есть Serial. Но я загружаю по USB asp, потом ставлю прошитую МК в устройство которое подключено к звуку. Т.е можно что-то организовать для проверки, но это уже не быстро. Точнее скзать, это уже нужно еще подумать как.

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

Сообщение olegue »

уже что то новое

Добавлено after 35 seconds:
там образец записнного wav файла

Добавлено after 20 seconds:
русский вернулся
Вложения
22-28-43.zip
(5.37 КБ) 59 скачиваний
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

второй канал измеряет напряжение

Добавлено after 1 minute 26 seconds:
ну и усредняет там было видно в коде, я там пытался чудить. Т.е измеряет напряжение на стандартных настройках АЦП analogRead(A0)

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

Сообщение olegue »

все то ж самое.

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

Сообщение olegue »

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

Сообщение olegue »

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

Добавлено after 1 minute 5 seconds:
если с компьюетра гнать, то нужен усилок, посмотрю где-то уменя что то было

Добавлено after 26 minutes 44 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=4244853#p4244853"]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:
чёто намудрили с буферами)))[/uquote]


может все таки вот это попробовать. Как по мне так вполне годный код. В прерывании просто переключаем каналы АДС

Добавлено after 1 minute 24 seconds:
почему это может не работать?

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

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

olegue писал(а):В прерывании просто переключаем каналы АДС
я сразу это предложил...
вы пошли не тем путём))
у вас есть готовый рабочий код... всё что надо - просто добавить переключатель каналов))
а вас понесло совсем не туда...
olegue писал(а):или вообще сделать 2 таймера и пускай каждый делает свое дело
опять не то...
olegue писал(а):почему это может не работать?
разберись с буферами...

что ты пишешь на флешку ? не пойму...

buf00[bufByteCount] = ADCH; // это функция записи на флешку ?

bufByteCount == 64 // а почему размер буфера 64 байта ?

ты пишешь по 64 байта ? в сектор по 512 байт ? а остальные 448 байт ? или ты их оставляешь пустыми ?

64 байта данных... 11111111111111111....
и 448 байта нулей... 0000000000000000000000000000000000000000000...
так что ли ? ))

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

Сообщение olegue »

roman.com писал(а):у вас есть готовый рабочий код... всё что надо - просто добавить переключатель каналов))
,

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

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

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

Сообщение olegue »

Может уже участники дискуссии потеряли нить ,я напомнью

Сейчас код пишет звук с канал А1 (ADMUX=0X61) и в этой части претензий нет - все в порядки
Нужно что бы одновременно с другого канала А0 оцифровывалось напряжение. И как я понимаю высокая степень дискретизации для А0 не важна. Десять значений за секунду, приведенных к среднему. Потом я вывожу это на экран
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

вот какраз с частотой звука было бы проще...
ускорил бы таймер, запускающий оцифровку в 2 раза и после каждо оцифровки делал бы ADMUX^=0x01;
так он бы чередовал каналы формируя стереофайл, а что там во втором канале, уже не так важно...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Ответить

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