Программа для записи аудио в ISD1700 и настройка Arduino: подробное руководство
Компоненты и материалы
| Компонент | Количество |
|---|---|
| Arduino Nano R3 | 1 |
| Макетная плата (breadboard) | 2 |
| Модуль записи/воспроизведения голоса ISD1760 | 1 |
| Кабель USB-A — Mini-USB | 1 |
| Аудиоразъём 3.5 мм | 2 |
| Блок питания 9V 1A | 1 |
| Модуль питания для breadboard 5V | 1 |
| Перемычки (набор) | 1 |
Программное обеспечение и сервисы
- ISD1700 Record Tool — архив со скетчем для Arduino и Windows-приложением
- Arduino IDE
О проекте
В одном из недавних проектов мне потребовалось озвучивать короткие текстовые сообщения. MP3-шилды с SD-картой казались избыточными, а «обучение» Arduino воспроизведению человеческой речи означало бы затрату всех ресурсов микроконтроллера на вспомогательную задачу, да и памяти не хватило бы в любом случае.
Краткий поиск выявил чипы серии ISD1700 для записи и воспроизведения голоса — SPI-управляемые, способные хранить сообщения длительностью до нескольких минут.
Голосовые сообщения были подготовлены заранее в виде отдельных файлов. Оставался вопрос: как записать их в память чипа. Программаторы для ISD1700 не широко распространены и стоят значительно дороже самих чипов. Находилась информация о самостоятельной сборке (источник), но я программист, а не радиолюбитель, поэтому хотел использовать стандартное оборудование — платы Arduino идеально подходили для этой роли.
Изучив даташит («ISD1700 Design Guide»), я понял, что существует аналоговый вход, через который можно записывать файлы. Для автоматизации процесса решил написать специальное ПО — ISD1700 Record Tool.
ISD1700 Record Tool позволяет записать набор аудиофайлов в ISD1700 через плату Arduino. ПО состоит из двух частей: скетча для Arduino (ISD1700.ino) и отдельного Windows-приложения (ISD1700.exe).
Скетч в ISD1700.ino написан для плат на базе ATMega328P (тестировался на Arduino Uno и Nano), но, вероятно, будет работать и на других платах.
Поддерживаемые чипы ISD1700:
- ISD1730
- ISD1740
- ISD1750
- ISD1760
- ISD1790
- ISD17120
- ISD17150
- ISD17180
- ISD17210
- ISD17240
Windows-приложение основано на аудиобиблиотеке BASS, поддерживающей наиболее популярные форматы: MP3, WAV, OGG и др.
1. Аппаратное подключение
Во время разработки использовался готовый модуль записи вместо отдельного чипа ISD1700. Перед попыткой других вариантов подключения настоятельно рекомендую изучить оригинальный даташит ISD1700.
Рис. 1–5 показывают мою аппаратную конфигурацию. Использовался Arduino Nano.

На маленькой макетной плате установлены два разъёма 3.5 мм (Рис. 2) — для аудиовхода (слева) и наушников (справа).


Рекомендую использовать отдельный блок питания, а не питать все компоненты от 5V-выхода Arduino — без внешнего питания у меня было много ошибок связи. Однако это может быть связано с плохим качеством проводов или другими причинами.


2. Прошивка Arduino
Подключите Arduino к ПК через USB, откройте ISD1700.ino в Arduino IDE и загрузите скетч как обычно (Рис. 6).

3. Интерфейс приложения
Запустите ISD1700.exe. Описание каждого элемента управления показано на Рис. 7.

4. Типовая последовательность работы
Рис. 8 показывает типичную операционную последовательность в Windows-приложении.

Описание:
- Откройте аудиофайлы для записи в ISD1700. Сортируйте их перетаскиванием мышью, удаляйте лишние (предварительно отметив) при необходимости. Можно прослушать каждый файл и отрегулировать громкость.
- Выберите COM-порт, к которому подключена плата Arduino (Рис. 9).
- Нажмите кнопку «Detect ISD1700» и убедитесь, что модель чипа отобразилась в поле справа.
- Убедитесь, что суммарная длительность всех аудиофайлов меньше ёмкости ISD1700 в секундах; иначе запись не начнётся.
- Нажмите «Start record». Прогресс виден на полосе. При необходимости нажмите «Stop record».
- После завершения можно скопировать адреса всех треков в буфер обмена. Рис. 10 показывает разницу между двумя опциями.


Использование модуля записи ISD1700 позволяет воспроизводить аудиофайлы сразу после записи с помощью наушников и кнопок на плате.
Код (Arduino)
// Arduino code for ISD1700 Record Tool
// Tested: Arduino Uno, Arduino Nano (ATMega328P)
// Copyright: Anton Tsaritsynskyy, August 2019
// E-mail: tsaritsynskyy.a.a@gmail.com
//
// This software is provided "as is" without any warranties.
// Author is not responsible for any undesired effects caused by using this software.
// Commercial distribution of this software is not permitted.
// Third-party libraries and components are properties of their respective developers.
#include
const unsigned int ISD_ERASE_OK = 3002;
const unsigned int ISD_REC_OK = 3003;
const unsigned int ISD_STOP_OK = 3004;
const unsigned int ISD_RESET_OK = 3005;
const unsigned int ISD_CANCEL_OK = 3006;
const unsigned int ISD_FULL = 3007;
const byte ISD_SS_PIN = 8;
boolean isdIsUp = false;
boolean isdNotifyIfFull = true;
boolean isdPowerUp(void) {
byte SR0B1 = 1;
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SR0B1 = SPI.transfer(0x01);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
return (SR0B1 & 1) != 1;
}
boolean isdPowerDown(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x07);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
}
boolean isdReset(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x03);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
delay(20);
}
void isdClrInt(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x04);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
}
boolean isdIsReady(void) {
byte SR1 = 0;
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x05);
SPI.transfer(0x00);
SR1 = SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
return (~SR1 & 1) != 1;
}
void isdEnableAnaIn(void) {
byte APC[2];
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x44);
SPI.transfer(0x00);
APC[0] = SPI.transfer(0x00);
APC[1] = SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
APC[0] &= ~B01010000;
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x45);
SPI.transfer(APC[0]);
SPI.transfer(APC[1]);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
}
byte isdDeviceID(void) {
byte ID;
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x09);
SPI.transfer(0x00);
ID = SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
return ID;
}
boolean isdIsFull(void) {
byte SR0B1 = 2;
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SR0B1 = SPI.transfer(0x05);
SPI.transfer(0x00);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
return (SR0B1 & 2) == 2;
}
void isdRec(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x41);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
delay(40);
}
void isdStop(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x02);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
delay(100);
}
void isdErase(void) {
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x43);
SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
while (!isdIsReady()) {}
}
unsigned int isdReadRecordPointer(void) {
byte DB[2];
SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));
digitalWrite(ISD_SS_PIN, LOW);
SPI.transfer(0x08);
SPI.transfer(0x00);
DB[0] = SPI.transfer(0x00);
DB[1] = SPI.transfer(0x00);
digitalWrite(ISD_SS_PIN, HIGH);
SPI.endTransaction();
return (DB[1] << 8) | DB[0];
}
unsigned int isdInit(void) {
while (!isdPowerUp()) {}
delay(100);
isdClrInt();
while (!isdIsReady()) {}
isdEnableAnaIn();
return 3000 + isdDeviceID();
}
void setup() {
pinMode(ISD_SS_PIN, OUTPUT);
digitalWrite(ISD_SS_PIN, HIGH);
Serial.begin(9600);
SPI.begin();
}
char cmd;
void loop() {
if (Serial.available()) {
cmd = Serial.read();
switch (cmd) {
case 'D':
Serial.print(isdInit());
isdPowerDown();
isdIsUp = false;
break;
case 'E':
isdInit();
isdErase();
Serial.print(ISD_ERASE_OK);
isdIsUp = true;
isdNotifyIfFull = true;
break;
case 'R':
isdRec();
Serial.print(ISD_REC_OK);
break;
case 'S':
isdStop();
Serial.print(isdReadRecordPointer());
break;
case 'X':
isdReset();
Serial.print(ISD_RESET_OK);
isdIsUp = false;
break;
case 'C':
if (isdIsUp) {
isdStop();
isdReset();
Serial.print(ISD_CANCEL_OK);
isdIsUp = false;
}
break;
}
}
if (isdNotifyIfFull && isdIsUp) {
if (isdIsFull()) {
isdReset();
isdIsUp = false;
Serial.print(ISD_FULL);
isdNotifyIfFull = false;
}
}
}
Схемы

Производственный процесс
- Достижение сертификации ISO 26262 для программных компонентов автомобилей
- Высокопроизводительные вольфрамо-титановые мишени для передовых полупроводниковых чипов
- Ультравысокочистые вольфрамные мишени: ключ к передовым полупроводниковым тонким пленкам
- AI-чип стартапы достигают плато: фокус индустрии смещается к in-house решениям
- Портативный пульсоксиметр для экстренного использования в условиях COVID-19
- Сборка аудиореактивной настольной лампы на Arduino Nano
- Метеостанция на Arduino и ThingSpeak: температура и влажность в облаке
- Автоматический ключ для радиолокации — точность, простота и надежность
- Health Band: умный браслет для мониторинга пожилых людей на Arduino Nano и DPS310
- Hexion Inc. подала на банкротство по главе 11 в рамках реструктуризации