ARDUINO Передача данных аудиосигналом с телефона на ардуино и обратно

Александро

✩✩✩✩✩✩✩
28 Окт 2018
0
1
Возникла идея передать данные аудиосигналом между телефоном и Arduino.
Всю информацию с ардуино можно выводить прямо на телефон и так же передавать любые значения на ардуино.
Это очень удобно так как для ардуино не потребуется ни экрана ни кнопок ни проводов вместо этого только динамик и микрофон которые можно найти буквально в мусоре.

Что потребуется:
Arduino;
Микрофон с цифровым преобразователем (например KY-037), подключаемый к цифровым выводам Arduino;
Динамик, подключаемый к цифровым выходам Arduino;
Телефон на Android;
Написать код для Arduino;
Создать приложение на телефон Android.
1775567276041.png1775567294948.png

Генерация звукового сигнала Arduino
Можно использовать встроенную библиотеку tone() для генерации звуковой волны заданной частоты.
Например, передаем последовательностью импульсов используя протокол UART.

Генерация звукового сигнала на стороне телефона
Можно использовать HTML для генерации звуковой волны заданной частоты.
Например, передаем последовательностью импульсов используя протокол UART.

Прием и обработка сигнала Arduino
Нужно написать код для анализа поступающего сигнала. Передать постоянный сигнал не получится поэтому нужно будет обработать поступающий меандр.

Прием и обработка сигнала на стороне телефона
Приложение должно записывать звук через микрофон и анализировать последовательность полученных сигналов (частоту и продолжительность), превращая её снова в бинарные данные. Знаний для создания Android приложений у меня нет и ограничивается лишь использованием MIT App Inventor 2 у которого нет дополнений для обработки звуковых сигналов полученных с микрофона. Хочу попытатся использовать тот же HTML.

Возможные проблемы:
Проблемы синхронизации при передаче большого объема данных.
Внешние шумы могут сильно влиять на качество приема, необходимо использовать методы проверки данных.
Проект требует хорошей инженерии и знания методов обработки цифровых сигналов.
 
Изменено:
  • Лойс +1
Реакции: Nellored

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
248
46
www.youtube.com
написал код на HTML для генерации UART сигнала 300 бод.
А какое практическое применение вашего изобретения?
Я понимаю, что так в прошлом веке программы загружались с магнитофона в компьютеры, но спустя 40 лет это зачем ?
 

Александро

✩✩✩✩✩✩✩
28 Окт 2018
0
1
Хочу передавать информацию между ардуино и телефоном без проводов, при этом использовать крайне дешевые элементы.
Можно на телефоне организовать интерфейс управления ардуино.
Хочу использовать потенциал старого сенсорного телефона и не использовать блютуз и вай фай.
 

Александро

✩✩✩✩✩✩✩
28 Окт 2018
0
1
Передаваемый сигнал имеет частоту 2000Гц (можно повысить).
По умолчанию передаетсся Hi то есть:
H - 1111011010 (10 бит)
i - 1011010010 (10 бит)
После записи на обычный диктофон видим картину:1775128653520.png
 
Изменено:

Александро

✩✩✩✩✩✩✩
28 Окт 2018
0
1
Передаваемый сигнал должен иметь выше частоту например 5 кГц.
Если скорость 300 бод тогда во временных промежутках в 3,33 мс измеряем кол-во импульсов.
Должно быть 16 (+/- 2).
Так и будем декодировать сигнал.
 

Александро

✩✩✩✩✩✩✩
28 Окт 2018
0
1
Написал с помощью ИИ код для декодирования сигнала.
Код нужно ещё дорабатывать и дорабатывать.
C++:
const int signalPin = 2;
volatile uint16_t edgeCount = 0;      // Счётчик изменений импульса (переходов)
uint32_t previousMicros = 0;
const uint32_t interval = 3330;

int currentBitIndex = 0;                // Индекс текущего бита (также определяет состояние)

uint8_t dataByte = 0;               // Байт для хранения битов 2–9

// Переменная для хранения предыдущего состояния пина
volatile bool lastState = false;

void setup() {
  Serial.begin(9600);  // Скорость Serial 9600 бод
  pinMode(signalPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(signalPin), countEdge, CHANGE);  // Прерывание на ЛЮБОЕ изменение
  previousMicros = micros();
  lastState = digitalRead(signalPin);  // Инициализируем начальное состояние
  Serial.println("Ожидание синхронизации... (ожидание первого '1')");
}

void loop() {
  uint32_t currentMicros = micros();

  // Проверка интервала
  if (currentMicros - previousMicros >= interval) {
    // Определение логического бита по количеству переходов за интервал
    bool receivedBit = (edgeCount >= 26 && edgeCount <= 34);  // 32 ± 6 переходов = логическая «1»

    // Состояние 1: ожидание синхронизации (currentBitIndex == 0)
    if (currentBitIndex == 0) {
      if (receivedBit) {
        // Нашли первый «1» — начинаем приём данных
        currentBitIndex = 1;  // Переходим к приёму первого бита после синхронизации
        dataByte = 0;         // Сброс байта при начале приёма
      }
      // Если receivedBit == false (т. е. «0»), просто игнорируем и ждём следующего интервала
    }
    // Состояние 2: приём битов (1 <= currentBitIndex <= 9)
    else if (currentBitIndex >= 1 && currentBitIndex <= 9) {
      // Записываем биты 2–9 (индексы 1–8 в отсчёте после синхронизации)
      if (currentBitIndex >= 2 && currentBitIndex <= 9) {  // Биты 2–9 соответствуют индексам 2–9
        dataByte = (dataByte << 1) | receivedBit;
      }
      currentBitIndex++;

      // Состояние 3: все 10 битов получены (currentBitIndex >= 10)
      if (currentBitIndex >= 10) {
        // Данные готовы к выводу
        Serial.print("B");
        Serial.println(dataByte, BIN);

        // Сброс для следующего цикла приёма
        currentBitIndex = 0;  // Возвращаемся в режим ожидания синхронизации
        dataByte = 0;       // Очищаем байт
        Serial.println("Ожидание следующей синхронизации... (ожидание первого '1')");
      }
    }

    // Сброс счётчика и обновление времени
    edgeCount = 0;
    previousMicros = currentMicros;
  }
}

// Обработчик прерывания: вызывается при ЛЮБОМ изменении состояния пина
void countEdge() {
  edgeCount++;  // Увеличиваем счётчик переходов
}