Аннотация

В статье дано подробное описание приложения, позволяющего обмениваться текстовыми сообщениями между Android-устройствами с помощью встроенных динамика и микрофона. Дана ссылка на полный исходный код, а для ключевых моментов приведены поясняющие блок-схемы. Приложение представляет практический интерес и готово к применению, работает достаточно стабильно и имеет большой потенциал для дальнейших экспериментов и улучшений. В ходе работы затронуты вопросы формирования звука, фильтрации, реализации скользящей средней, сохранения и оцифровки аналогового сигнала. Материал может быть рекомендован в первую очередь начинающим разработчикам для повторения и закрепления указанных тем.

Введение. Проблема. Цель

Во-первых, большое количество людей регулярно используют рации, потому что это, с одной стороны, удобно, а с другой – иногда и вовсе не имеет альтернатив. Область применения очень широкая: от активного отдыха до чрезвычайных ситуаций. И, как правило, функционал раций покрывает все нужды в своей нише, но, учитывая, что мобильный телефон всегда под рукой, хотелось бы попробовать сочетать утилитарность раций и удобство смартфона. Даже возможность передать просто координаты по радиоканалу в рамках своей туристической группы – это уже интересно, но что, если передавать зашифрованные сообщения или даже графические данные? Для меня, как для туриста со стажем, это представляется по меньшей мере любопытным.

На Хабре широко рассмотрен вопрос передачи данных звуком:

Кроме детальных обзоров на проекты wave-share и ozzilate здесь есть впечатляющие материалы на такие темы, как, например, передача видео под водой звуком или скрытое общение с помощью ультразвука. Однако, несмотря на проработанность вопроса, попытка реализовать идею в готовом программном решении с учетом специфики и ресурсов смартфона, работающего на ОС Android, является новой, а предлагаемый проект закрывает этот пробел.

Передатчик

Послать сигнал, как правило, намного проще, чем распознать этот сигнал и верно его интерпретировать. В данном случае, это именно так. В текущей версии приложения для формирования сигнала выбрана OOK модуляция несущей, как самый простой вариант. Главные недостатки – это низкая помехоустойчивость и сильная зависимость от расстояния, ведь практически всё сводится к отношению амплитуды сигнала к амплитуде шумов. Главный плюс – наглядность и простота реализации.

В приложении два активити, из которых одно реализует передатчик (слева), а другое – приемник (справа):

Внешний вид передатчика (слева) и приемника (справа)
Внешний вид передатчика (слева) и приемника (справа)

Передатчик на вход принимает три параметра: частота несущей freq (Гц), продолжительность одного бита duration (мс), текст сообщения одной строкой StringBuffer textbuffer.

Формирование сигнала происходит следующим образом. Сначала текст сообщения преобразуется в набор бит:

текст → байты → BitSetArrayList <Boolean> booleanList

Одновременно с этим создается аудио сэмпл для передачи бита, равного единице:

//one bit sine array initialization
for (int i = 1; i < numSamples; ++i)
{
   samples[i] = Math.sin(2 * Math.PI * i / (sampleRate/freq)); // Sine wave
   buffer[i] = (short) (samples[i] * Short.MAX_VALUE);  // Higher amplitude increases volume
}

где

int sampleRate = 44100 – частота дискретизации источника в Гц. 

int numSamples = (int) (sampleRate*duration)количество значений для передачи одного бита.

Для передачи бита, равного нулю, используется тишина. Поэтому итоговое аудио сигнала формируется так:

 //Wave to output. 1-sine, 0-zero
for (int i=0; i<booleanList.size(); i++)
{
   if(booleanList.get(i))
   {
       for (int k=0;k<buffer.length;k++)
       {
           audioBuffer.add(buffer[k]);
       }
   }
   else
   {
       for (int k=0;k<buffer.length;k++)
       {
           audioBuffer.add((short)0);
       }
   }
}

Таким образом блок-схема передатчика:

Алгоритм формирования сигнала из текстового сообщения
Алгоритм формирования сигнала из текстового сообщения

Для проигрывания полученного сигнала использован класс AudioTrack. Сообщение передается слева направо, причем в каждом байте сначала идут младшие биты. 

Вот пример уже озвученного и записанного на диктофон сигнала, передающего текстовое сообщение из трех букв латинского алфавита, имеющего следующие параметры: частота несущей – 500 Гц, продолжительность бита – 300 мс:

Пример сформированного сигнала.
Пример сформированного сигнала.

Приемник

При реализации приемника было необходимо ответить на ряд известных вопросов: как понять, что начался именно сигнал, как отделить сигнал от шума и помех, как обеспечить приемлемый уровень стабильности распознавания.

Известным ответом на часть озвученных вопросов является наличие преамбулы. Для начала была добавлена 10-битная преамбула “1010101010”. Она дает возможность синхронизировать приемник и понять ему, где сообщение начинается. Размер должен отвечать по меньшей мере двум взаимоисключающим требованиям: быть достаточно долгим, чтобы исключить ложное детектирование и быть исчезающе малым, чтобы не тратить эфирное время. В передатчике преамбула добавляется в начало booleanList уже ПОСЛЕ того, как текст переведен в биты:

//Add the preambula at the beginning
//1010101010

for (int i=0; i<=9; i++)
{
   if(i%2==0)
   {
       booleanList.add(0,false);
   }
   else
   {
       booleanList.add(0,true);
   }
}

С учетом преамбулы то же самое сообщение будет выглядеть так:

Сигнал с учетом преамбулы
Сигнал с учетом преамбулы

Но преамбулу, как и все остальное, необходимо еще “разглядеть” среди шума и помех, что было решено с помощью полосового фильтра, реализованного в библиотеке ddf.minim.effects Class BandPass:

floatedValues=new float[file.length];
for (int i=0; i<file.length; i++)
{
   floatedValues[i]=file[i];
}
bandpass.process(floatedValues);

В первую очередь необходимо зафиксировать сигнал, для чего используется класс AudioRecord:

int SAMPPERSEC = 44100;
int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
audioRecord = new AudioRecord(
    android.media.MediaRecorder.AudioSource.MIC,
       SAMPPERSEC,
       channelConfiguration,
       audioEncoding,
       bufflen10
);

где bufflen = AudioRecord.getMinBufferSize(SAMPPERSEC, channelConfiguration, audioEncoding). Здесь bufflen вычисляется для каждого смартфона отдельно, потому что есть ограничения на минимальный размер этого буфера, что обусловленно производителем.

Чтобы приложение не зависало во время записи, это делается в отдельном потоке, который выдает только небольшие массивы измерений, обрабатываемых в основном потоке. При этом используется циклический буфер, чтобы данные не стирались, пока идет обработка. Т.е. после получения от AudioRecord'a массива данных data, идет их передача в handleMessage Handler'a основного потока:

// 1. В потоке, записывающем аудио:
private void sendMsg(short[] data)
{
  for(Handler handler : handlers)
  {
    handler.sendMessage(handler.obtainMessage(MSG_DATA, data));
  }
}

// 2. В основном потоке:
h = new Handler(Looper.getMainLooper()) 
{
  public void handleMessage(android.os.Message msg)
  {
    if(msg.what == thread.THREAD_END)
    {
      thread.interrupt();
    }
    else
    {
      saveFile((short[]) msg.obj);
    }
  }
};

В методе saveFile происходит основная работа с сигналом. В текущей версии приложения эта работа состоит в фильтрации и усреднении данных, поиске преамбулы и распознавании сигнала. С целью визуализации и отладки происходит также сохранение "сырых" данных в файле obtainedValues.txt, отфильтрованных данных – в файле filteredValues.txt и усредненных данных – в processedValues.txt. Форматирование данных в этих файлах оптимизировано для работы в Matlab, где их можно, например, открыть одновременно:

fileID = fopen('obtainedValues.txt','r');
formatSpec = '%d';
sizeA = [Inf];
A = fscanf(fileID,formatSpec,sizeA);

plot(A);
fclose(fileID);

fileID_2 = fopen('filteredValues.txt','r');
formatSpec = '%f';
sizeA_2 = [Inf];
A_2 = fscanf(fileID_2,formatSpec,sizeA_2);

hold on;
plot(A_2);
fclose(fileID_2);

fileID_3 = fopen('processedValues.txt','r');
formatSpec = '%f';
sizeA_3 = [Inf];
A_3 = fscanf(fileID_3,formatSpec,sizeA_3);

hold on;
plot(A_3);
fclose(fileID_3);

Файлы нужно перетащить из папки Android>data>audiorecorder в папку со скриптом и в результате исполнения данного скрипта получаем наглядное представление записанного сигнала:

Результаты фильтрации
Результаты фильтрации

Здесь видно, что фильтрация хорошо справляется, и человек теперь без труда увидел бы сигнал невооруженным взглядом, но для дальнейшего распознования нужно формализовать "объяснить" программе, что конкретно является сигналом. По аналогии с детекторным приемником для этого было решено перенести все отрицательные значения наверх заменой знака (или просто заменить отрицательные значения нулями) и усреднить скользящей средней, после чего получается следующее:

Синяя линия – исходные данные, красная – фильтрованные, оранжевая – скользящая средняя
Синяя линия – исходные данные, красная – фильтрованные, оранжевая – скользящая средняя

После этого можно сравнить скользящую среднюю с некоторым пороговым значением и принять решение о дальнейших действиях, например, предположить, что получена единица или ноль. Если удачно "попасть" в середину меандра, то всё отлично распознается, но есть значительная вероятность выбрать момент, когда высокий уровень сменяется низким. В этом случае никакой синхронизации не получится, и данные будут утеряны. Чтобы избежать этой проблемы, приложение ищет преамбулу одновременно дважды: со сдвигом на половину продолжительности бита и без сдвига. Какой-то из этих двух поисков точно будет синхронизирован с сигналом, после чего уже начнется распознавание:

Hidden text
//1 Looking for preambula. Non-shifted
        if(!isPreambula)
        {
            while( !isBufferEnd1 && !isPreambula )
            {
                if ((preambulaCounter1 % 2) == 0)
                {
                    if ( sampleIndex1 < file.length)
                    {
                        if (movingAverageValues[sampleIndex1] > bitThreshold)
                        {
                            preambulaCounter1++;
                        }
                        else
                        {
                            preambulaCounter1 = 0;
                        }
                    }
                    //если индекс не помещается в этом буфере
                    else
                    {
                        sampleIndex1 = sampleIndex1 - file.length;
                        isBufferEnd1 = true;
                    }
                }
                else
                {
                    if ( sampleIndex1 < file.length)
                    {
                        if (movingAverageValues[sampleIndex1] < bitThreshold)
                        {
                            preambulaCounter1++;
                        }
                        else
                        {
                            preambulaCounter1 = 0;
                        }
                    }
                    //если индекс не помещается в этом буфере
                    else
                    {
                        sampleIndex1 = sampleIndex1 - file.length;
                        isBufferEnd1 = true;
                    }
                }

                //IF sampleIndex bigger than buffer size THEN interrupt 'while'
                if(isBufferEnd1) break;

                //if needed sample in this(current) massive
                if ( (sampleIndex1 + numSamples) < file.length)
                {
                    sampleIndex1 = sampleIndex1 + numSamples;
                }
                //if needed sample is in the next massive
                else// ЗДЕСЬ ТОЖЕ КОСЯК
                {
                    numberToEnd = file.length - sampleIndex1;
                    sampleIndex1 = numSamples - numberToEnd;
                    isBufferEnd1=true;
                }

                if (preambulaCounter1 == 9)
                {
                    isPreambula = true;
                    sampleIndex = sampleIndex1;
                    isBufferEnd = isBufferEnd1;

                    //print Preambula
                    showMessageSB = new StringBuilder();
                    showMessageSB.append("Preambula has been detected");
                    messageOutput.setText(showMessageSB.toString());
                }
            }
            isBufferEnd1 = false;
        }

        //2 Looking for preambula. Shifted numSamples/2 to the right
        if( !isPreambula )
        {
            while( !isBufferEnd2 && !isPreambula )
            {
                if( (preambulaCounter2 % 2) == 0)
                {
                    if ( sampleIndex2 < file.length)
                    {
                        if (movingAverageValues[sampleIndex2] > bitThreshold) {
                            preambulaCounter2++;
                        } else {
                            preambulaCounter2 = 0;
                        }
                    }
                    //если индекс не помещается в этом буфере
                    else
                    {
                        sampleIndex2 = sampleIndex2 - file.length;
                        isBufferEnd2 = true;
                    }
                }
                else
                {
                    if ( sampleIndex2 < file.length)
                    {
                        if(movingAverageValues[sampleIndex2] < bitThreshold)
                        {
                            preambulaCounter2++;
                        }
                        else
                        {
                            preambulaCounter2 = 0;
                        }
                    }
                    //если индекс не помещается в этом буфере
                    else
                    {
                        sampleIndex2 = sampleIndex2 - file.length;
                        isBufferEnd2 = true;
                    }
                }

                //IF sampleIndex bigger than buffer size THEN interrupt 'while'
                if(isBufferEnd2) break;

                //if needed sample in this(current) massive
                if((sampleIndex2 + numSamples) < file.length)
                {
                    sampleIndex2 = sampleIndex2 + numSamples;
                }
                //if needed sample is in the next massive
                else
                {
                    numberToEnd = file.length - sampleIndex2;
                    sampleIndex2 = numSamples - numberToEnd;
                    isBufferEnd2 = true;
                }

                if(preambulaCounter2 == 9)
                {
                    isPreambula = true;
                    sampleIndex = sampleIndex2;
                    isBufferEnd = isBufferEnd2;

                    //print Preambula
                    showMessageSB = new StringBuilder();
                    showMessageSB.append("Preambula has been detected");
                    messageOutput.setText(showMessageSB.toString());
                }
            }
            isBufferEnd2 = false;
        }

        //3 Reading the message
        if( isPreambula )
        {
            while(!isBufferEnd)
            {
                if ( sampleIndex < file.length )
                {
                    if (movingAverageValues[sampleIndex] > bitThreshold)
                    {
                        //showMessageDataSB.append("1");
                        //messageData.setText(showMessageDataSB.toString());
                        datum = datum | (1 << (bitIndex1-1));
                    }
                    else
                    {
                        //showMessageDataSB.append("0");
                        //messageData.setText(showMessageDataSB.toString());
                    }
                    bitIndex1++;
                    if ( bitIndex1 == 8)
                    {
                        showMessageDataSB.append( (char) datum );
                        messageData.setText(showMessageDataSB.toString());
                        bitIndex1 = 0;
                        datum = 0;
                    }
                }
                //если индекс не помещается в этом буфере
                else
                {
                    sampleIndex = sampleIndex - file.length;
                    isBufferEnd = true;
                }

                //IF sampleIndex is bigger than buffer size THEN interrupt 'while'
                if (isBufferEnd) break;

                //if needed sample in this(current) massive
                if( (sampleIndex + numSamples) < file.length)
                {
                    sampleIndex = sampleIndex + numSamples;
                }
                //if needed sample is in the next massive
                else
                {
                    numberToEnd = file.length - sampleIndex;
                    sampleIndex = numSamples - numberToEnd;
                    isBufferEnd = true;
                }
            }
            isBufferEnd = false;
        }
        else
        {
            showMessageSB = new StringBuilder();
            showMessageSB.append(String.valueOf(preambulaCounter1));
            showMessageSB.append(String.valueOf(preambulaCounter2));
            messageOutput.setText(showMessageSB.toString());
        }
        isBufferEnd=false;

Большое количество проверок связано с тем, что данные подаются сравнительно маленькими массивами и требуется постоянно ждать следующую порцию и ориентироваться, в каком моменте времени находится интересующий замер. В приемнике сообщение будет выводиться в режиме реального времени, что немного компенсирует невысокую скорость передачи.

Дополнительно, нужно отметить, что передатчик работает без каких-либо предварительных настроек, но приемник для запуска и работы требует разрешений на использование микрофона и работы с хранилищем данных:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

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

Демонстрация

На видео представлена работа текущей версии приложения:

Выводы и планы

Во-первых, достигнута поставленная цель: приложение действительно позволяет расширять функционал рации до передачи текстовых сообщений. Однако нет принципиальных ограничений для передачи, например, картинки, и это планируется сделать в первую очередь. Во-вторых, вопросы вызывает скорость и стабильность распознавания. Требуется провести ряд экспериментов, чтобы набрать статистику для оценки качества функционирования. В-третьих, выбранная для пробы пера модуляция годится лишь при демонстрации. Поэтому в ходе дальнейшей работы планируется попробовать частотную модуляцию и линейно-частотную модуляцию, чтобы добиться лучшей помехоустойчивости и скорости передачи. В-четвертых, примененные алгоритмы детектирования и распознавания не привязаны к каким-либо особенностям именно встроенных динамиков и микрофонов, то есть их можно использовать и с сигналами другой природы.

Ссылка на репозиторий

Полный исходный код и весь проект лежит здесь.

Комментарии (34)


  1. DreamingKitten
    23.10.2022 00:23
    +2

    1. RomanBashmakov Автор
      23.10.2022 00:39

      Интересно, по описанию вроде что-то похожее, но надо попробовать, спасибо!


  1. victor_1212
    23.10.2022 01:32
    +7

    > Поэтому в ходе дальнейшей работы планируется попробовать частотную модуляцию и линейно-частотную модуляцию, чтобы добиться лучшей помехоустойчивости и скорости передачи.

    т.е. сделать модем, исторически следующим этапом был x.25, может быть стоит посмотреть стандарты


    1. bombardier
      23.10.2022 10:55
      +1

      Тогда уж можно смотреть в сторону AX.25


      1. victor_1212
        23.10.2022 19:09

        был такой модуль ax25.ko, типа linux native AX.25, возможно будет полезен,

        также см.

        https://fedoraproject.org/wiki/AmateurRadio

        https://wiki.archlinux.org/title/Amateur_radio

        https://xastir.org/index.php/HowTo:AX25_Fedora


  1. AllKnowerHou
    23.10.2022 02:56

    И какая дальность между приемником и передатчиком?


    1. buldo
      23.10.2022 04:49
      +3

      Это же радио. Правильный ответ - "зависит". Зависит от кучи переменных - мощности, антен, рельефа, погоды...


      1. Moraiatw
        23.10.2022 11:00
        -2

        Это вообще смартфон. Передача через голосовой канал через мобильную сеть.


  1. buldo
    23.10.2022 04:47

    Или можно сразу купить цифровые станции.

    А если копать дальше, то можно просто выбрать один из готовых способов передачи цифровых данных по а налоговому радио с это страницы вики https://en.m.wikipedia.org/wiki/Selective_calling


  1. Fodin
    23.10.2022 04:52

    Меня ностальгией накрыло только от заголовка, не говоря уже о содержании статьи, а для кого-то это изобретение. "Изобретение модема" - звучит!


    1. inkelyad
      23.10.2022 13:52

      'Настоящие' связисты редко пишут статьи и софт.

      Скажем, вот у нас есть всякие Bluetooth, NFC, WiFi, сканирование QR-кодов в контексте 'оплатить покупку'. Каждый из способов, вообще говоря, требует оборудования в железке, которого может либо не быть, либо параметры не подходят (камера вроде у каждого смарта есть, но теми, что в дешевых моделях, ничего просканировать нормально нельзя).

      Однако, как я понимаю, даже на такой камере и небольшом количестве просто чего-нибудь светящегося (светодиод, кусок экрана) можно как-нибудь способ передачи информации сделать. Кроме того - у каждого смарта и динамик и микрофон есть. Которые тоже можно как-нибудь задействовать для передачи пары сотен байт.

      И где решения? А если их нет - то почему?


  1. ivanstor
    23.10.2022 07:14
    +2

    В плане познавательном, для автора и читателей — эту работу можно только приветствовать. Поэтому поставил лайк.
    Но для практического применения не подходит.
    Передачи данных по радиоканалу — сложная задача, особенно по узкополосному и зашумленному. Вот так, в полпинка её не решить. К счастью, всё уже сделано до нас.
    Вот, например, обзор приложения для смартфона как раз заточенного под такую задачу:
    https://lasto.com/blog/index_post_1569308400.htm
    А вот обзорная статья по цифровой (любительской) радиосвязи на хабре:
    https://habr.com/ru/post/128003/


    1. inkelyad
      23.10.2022 11:40
      +1

      C AndFlmsg весело играться даже без рации - просто акустикой. Берешь два смарта, настраиваешь модуляцию Olivia 4/250, заходишь в шумную комнату - и оно вот сквозь весь этот шум ухитряется меееееедленно, но совершенно неслышно для уха сообщения передавать. А если еще воспользоваться обычными водопроводными трубами - развлечение на день обеспечено.


      1. ivanstor
        23.10.2022 12:28

        Ага. Завораживает.


  1. wizard_s
    23.10.2022 08:55

    https://hfpager.com/hfpager/hf-pager

    Готовый софт для туристов, правда в полной версии платно.

    Еще существуют программы под телефон для ft8, jt65, psk. И библиотеки для этих протоколов. Изобретать свое не имеет смысла, имхо, нужно пользоваться готовыми протоколами и либами.


  1. Javian
    23.10.2022 10:17
    +1

    Есть APRSdroid для Андроид

    APRSdroid - это приложение для Android для радиолюбителей. Это позволяет сообщать о вашем местоположении в сеть APRS (Automatic Packet Reporting System), отображать близлежащие любительские радиостанции и обмениваться сообщениями APRS.

    Кабель для подключения телефона к рации.


  1. Sau
    23.10.2022 11:24

    Для передачи изображений через звук есть SSTV, можно передавать хоть по рации (обычно так его и используют).

    Для него есть приложения для телефонов и ПК, не требуется изобретать и поддерживать новый стандарт.

    Статья на английском с примерами картинок и звуковых дорожек: https://www.sigidwiki.com/wiki/SSTV


    1. inkelyad
      23.10.2022 14:14

      Еще близкая идея. Было вот такое устройство: Hellschreiber.

      Пара роликов о том, как работа выглядит: раз, два

      И пара необычайно залипательных сайтов от энтузиастов факсов и телетайпов: раз, два. Там много разного исторического low-tech-а


  1. inkelyad
    23.10.2022 11:31

     если передавать зашифрованные сообщения

    Я так понимаю, на подобную идею очень, очень косо смотрят. Потому и не так чтобы распространено.


    1. MAXH0
      23.10.2022 17:17

      НО что мешает? Аппарат то есть.


      1. buldo
        23.10.2022 17:25

        Вроде как есть законодательные ограничения на использование шифрования для любительской радиосвязи.


        1. MAXH0
          23.10.2022 17:42
          -1

          "Вроде" = плохой аргумент.

          1. Требуется точное определение что запрещено - ввоз, продажа использование.

          2. Разнести транспортный протокол и протокол шифрования. По радио мы просто обмениваемся файлами с планшетов/сотовых. Какие пакеты выдают устройства - следующий вопрос. Все! На радио просто нашлепка модема.

            У меня вообще представление что автор работы модем переизобретает. Потому что дальше пойдет пакетная передача, подписи пакетов, запросы на передачу утерянных пакетов и все прочие радости стандартных протоколов.


          1. inkelyad
            23.10.2022 17:50

            "Вроде" = плохой аргумент.

            Опять же есть подозрение, что это продолжение истории со шпиономанией тянущейся еще... с давно. И не только у нас.

            Вот если люди из аббревиатурных контор запеленгуют сигнал, что не смогут понять - придут ли для того, чтобы задавать неудобные вопросы и проводить воспитательные беседы?

            У меня вообще представление что автор работы модем переизобретает.

            Разумеется. Потому что уже изобретенных в видимом пространстве - всего нечего.


            1. MAXH0
              23.10.2022 18:22

              Вам не кажется что:
              1. "все остальное, необходимо еще “разглядеть” среди шума и помех..."
              2. Чем текстовый радиосигнал сигнал в этом отношении будет отличаться от шифрованого. А если вы картинку передаёте? А если телеметрию с датчиков?
              3. В 80 е годы прошлого века были звуковые модемы на телефонную трубку. Я думаю, они с задачей бы справились. Возможно я ошибаюсь.


              1. inkelyad
                23.10.2022 18:32

                "все остальное, необходимо еще “разглядеть” среди шума и помех..."

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

                 Чем текстовый радиосигнал сигнал в этом отношении будет отличаться от шифрованного. А если вы картинку передаёте? А если телеметрию с датчиков?

                Однако легко доступной, не требующей регистрации аппаратуры для текстового сигнала (особенно чтобы этот тестовый сигнал можно было подать снаружи) -- где такое? У нас даже общение через месседжеры с географически близкими людьми через сервера где-то на другом континенте работают.

                Хотя казалось бы - давно пора встроить во все смарты в качестве средства аварийной связи. Чтобы коротенькое 'я вот тут такой по координатам есть' хотя бы на единицы километров без базовых станций можно было передать.


                1. DreamingKitten
                  23.10.2022 18:42

                  У нас даже общение через месседжеры с географически близкими людьми через сервера где-то на другом континенте работают.

                  FireChat ?

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

                  именно на аварийный случай существуют аварийные маяки.


                  1. inkelyad
                    23.10.2022 18:47

                    именно на аварийный случай существуют аварийные маяки.

                    Аварийная связь по своей природе такая, что о ней почти никто не думает, пока она не понадобиться. Оно должно быть встроено в то, что у человека почти наверняка с собой есть. Т.е. в современных реалиях - в смарт.

                    FireChat?

                    В 'диких' условиях для потерявшегося человека - не работает. Собственно, оно, кажется, вообще как-то очень плохо работает вообще и дальше пары метров - в особенности.


                    1. 0x131315
                      24.10.2022 00:19

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


          1. buldo
            23.10.2022 18:08

            Аргумент? Я вроде не спорил, а просто поделился смутными воспоминаниями из давно покинутой сферы деятельности


        1. Javian
          23.10.2022 18:27

          Поискал литературу времен СССР. Всё очень строго было:

          Эксплуатация приемно-передающих радиоустройств независимо от их назначения (любительская радиосвязь, управление моделями и т. д.) требует наличия соответствующего разрешения Государственной инспекции электросвязи СССР, без которого выход в эфир запрещается. За изготовление, хранение и использование радиопередающих устройств без такого разрешения владельцы этих устройств несут ответственность.
          ***
          Владелец любительской радиостанции должен заблаговременно поставить в известность Государственную инспекцию электросвязи об изменении местонахождения радиостанции (при переносе внутри населенного пункта — за 5 дней, в другой населенный пункт — за 10 дней). Разрешение на перенос в пределах одной области дает областное управление Государственной инспекции электросвязи. При переезде владельца любительской радиостанции в другую область оформляется закрытие радиостанции по старому месту жительства. Порядок получения разрешения на работу индивидуальной любительской радиостанции по новому месту жительства владельца тот же, что и на вновь открываемую радиостанцию. При этом учитывается категория радиостанции, которую имел владелец на старом месте жительства

          ***
          Радиолюбители могут входить в связь только с любительскими радиостанциями и производить обмен информацией исключительно по вопросам, касающимся технических данных своей аппаратуры, проводимых связей и радиоспорта. Радиосвязи можно проводить как открытым текстом, так и международным Q-кодом (табл. 13) и любительским радиокодом (табл. 14).
          ***
          За нарушение «Инструкции о порядке регистрации и эксплуатации любительских приемно-передающих радиостанций индивидуального и коллективного пользования» и правил работы в эфире к владельцам любительских радиостанций могут быть применены различные меры взыскания: от предупреждения до полного закрытия радиостанции и аннулирования разрешения.
          Помимо указанных в табл. 1 видов излучения, любительские радиостанции могут работать телетайпом (буквопечатающая аппаратура, RTTY). Право использования RTTY представляется наиболее опытным радиолюбителям, имеющим радиостанции I категории, по отдельному ходатайству ФРС СССР


          Борис Григорьевич Степанов СПРАВОЧНИК КОРОТКОВОЛНОВИКА 1974


  1. MAXH0
    23.10.2022 12:23

    Как я понимаю ваш кейс направлен на то, чтобы в условиях отсутствия/отключения/подавления/уничтожения базовых станций смартфон оставался средством связи, а не простой игрушкой (ну или баллистическим калькулятором - если установлен нужный софт)...

    Или это чисто моя паранойя.


  1. dcc0
    23.10.2022 13:40

    Благорность автору. Попробуем. Тема крайне интересная.
    Всегода в походе хотелось рацию с поддержкой текстовых сообщений.
    Лежишь вечером в палатке и пишешь в соседний лагерь в километре от себя о планах на завтра.
    Есть еще вариант прямой связи между смартфонами через приложение Upd Sender/Receiver,
    по UDP.


  1. dcc0
    23.10.2022 15:08

    Видео в статье не отображается. FireFox 105.0.2 и Chrome 9.0.47.
    Видимо, нужно поправить теги или просто дать ссылки.
    Хотелось бы готовый .apk для тестирования.


  1. Dr_Faksov
    24.10.2022 07:36

    В большинстве стран мира радиолюбителям запрещена шифрованная радиосвязь.