Добрый день! Помогите разобраться с чего начать. Есть ардуино уно и Ethernet shield Необходимо чтобы звук приходящий с аналогового микрофона, подключенного к аналоговому входу ардуино передать по сети на удаленный компьютер Есть ли какие то идеи или возможно пример Как преобразовать звук в сетевой пакет и передавать по сети??
Пока не знаю, возможно на VB.net, что то буду писать, Изначально wiresharkoм посмотрю приходят пакеты, а дальше буду гуглить, Хотел узнать может у кого какой опыт есть или идей
Вопрос был серьезный. Только не про то, умеете ли вы ткнуть по первой ссылке из гугла. Считать звук с микрофона на ардуино это весьма нетривиальная задача, требующая опыта как в программировании. так и в аналоговой обработке звука. И даже с этим приличного качества добиться не получится. Лучше опишите подробно задачу. а вам посоветуют, как лучше это реализовать.
Занимался передачей голоса по IP. Могу примерно рассказать как это делается. Звук оцифровывается с частотой 8 кГц. Затем выбираем голосовой кодек который позволяет сжать эти данные и существенно уменьшить скорость необходимую для передачи. Обычный PCM A-закон дает 64 кбит/сек, ADPCM - 32, 24 или 16 кБит/сек. Если хотите еще сильнее пожать то G726, G729. Дольше накапливаете данные 10 или 20 мсек и пакуете в UDP-пакет. Пакет передаете на компьютер, распаковываете, декодируете и с частотой 8 кГц выдаете на ЦАП. Это все упрощенно, а более детально почитайте про IP-телефонию.
Есть небольшие опыт в электронике и побольше опыт в программирование и большой опыт по работе с ГУГЛОМ, ну и так же немного свободного времени(до наступления садово огородных работ ) Если по существу, то есть ethernet shield b arduino uno,. необходимо к аналоговому входу арудуино подключить микрофон (в принципе это сделано и проверено взят за основу скетч написанный Дмитрием , голос на SD карту находящуюся на shielde W5100 пишется приемлемый) Необходимо через тот же shield w5100 передавать пакеты (buffer) по udp протоколу, на удаленный компьютер в сети. Как то так
Спасибо за ответ, попробую порыть в сторону SIP Вопрос Я так понял, что звук сжимается с помощью микроконтроллера и только потом отправляется на удаленный ПК?? Хватит ли памяти у ардуино?
SIP - это протокол установления соединения в IP-телефонии. Для вас он не актуален. Пожать голос с помощью AVR-проблематично. Поэтому вы можете данные полученные с АЦП (10 бит) преобразовать в 1 байт (отбросить младшие разряды). Накопить 1250 отсчетов - это за 10 мс с частотой 8 кГц. Упаковать эти данные в UDP-пакет и передать через Ethernet. С другой стороны распаковать и с частотой 8 кГц выдать на ЦАП. Не уверен что это можно сделать с помощью ШИМ. Я на AVR использовал простейший R-2R ЦАП на одном из портов и получал приемлемые результаты.
Спасибо, вопрос что значить накопить 1250 отсчетов - это имеется ввиду накопить данные в буфер (за 10 мс с частотой 8 кГц) и передать этот буфер через UDP протокол на удаленный комп?? Я правильно вас понял?
Два вопроса Собрал код передает данные по udp на удаленный ПК взятые с аналогового входа к которому подключен микрофон Вопрос первый Выводится в serial порт следующие данные My IP address: 192.168.1.33Received packet of size 1 From 192.168.1.176, port 3539 Contents: 41 Received packet of size 1 From 192.168.1.176, port 3539 Contents: 40 На удаленном компе в консоле cmd(подключаюсь netcat) принимаются не числа как в сериал порту, а * ) и другие символы в зависимости от уровня звука принимаемого на микрофоне Как это изменить, что делаю не так, видимо тип данных не тот, тогда почему в сериал порт выводятся числа??? И второй вопрос и лучше на примере Для того чтобы захватить звук я так понимаю нужно затолкать в передаваемый пакет диапазон(массив) передаваемых данных (а не одно значение как у меня) Подскажите как это реализовать, лучше еще раз повторюсь на примере Заранее благодарен! Код (C++): #include <SPI.h> // требуется для Arduino версий 0018 и позже #include <Ethernet.h> #include <EthernetUdp.h> // библиотека UDP library (из bjoern@cs.stanford.edu 12/30/2008) //KY-037 микрофонный модуль - аналоговый выход A0 int microphonePin = A0; // выбор пина для входа от микрофона int microphoneValue = 0; // переменная для хранения значения от микрофона // IP-адрес : byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 33); unsigned int localPort = 8888; // локальный порт, который будем прослушивать // буферы для получения и отправки данных char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // буфер, в котором будет храниться входящий пакет char ReplyBuffer[] = "HELLO "; // строка, которая будет отсылаться обратно // Создаем класс EthernetUDP, чтобы отправлять и получать пакеты через UDP: EthernetUDP Udp; void setup() { // Запускаем Ethernet и UDP: Ethernet.begin(mac,ip); Udp.begin(localPort); Serial.begin(9600); Serial.print("My IP address: "); Serial.print(Ethernet.localIP()); } void loop() { // Если есть какие-либо доступные данные, считываем пакет: int packetSize = Udp.parsePacket(); if(packetSize) { Serial.print("Received packet of size "); // "Получен пакет размером " Serial.println(packetSize); Serial.print("From "); // "От " IPAddress remote = Udp.remoteIP(); for (int i =0; i < 4; i++) { Serial.print(remote[i], DEC); if (i < 3) { Serial.print("."); } } Serial.print(", port "); // ", порт " Serial.println(Udp.remotePort()); // Считываем пакет в packetBufffer: Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); Serial.println("Contents:"); // "Содержимое:" Serial.println(packetBuffer); // Отсылаем ответ. Получатель – IP-адрес и порт, // от которых пришел полученный нами пакет: mic(); Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); Udp.write(microphoneValue); //Udp.write(ReplyBuffer); Udp.endPacket(); } delay(10); } void mic(){ microphoneValue = analogRead (microphonePin); //чтение значения с аналогового входа delay (microphoneValue); Serial.println (microphoneValue, DEC); // вывод значения в монитор порта String buff = String (microphoneValue, DEC); buff.toCharArray(ReplyBuffer, 1); //Serial.println (ReplyBuffer); Serial.println (microphoneValue); }
Как раз числа и принимаются, а netcat их пытается декодировать в cp866. Пример работы с буфером есть в вашем же коде. Попробуйте разбирать примеры из интернета, а не просто копировать.
В моем коде есть пример работы с буфером, но нет примера работы как захватить несколько значений за определенный промежуток времени или просто определенное количество.(Я поэтому и прошу совета как реализовать) И примеры которые я беру из интернета я обычно разбираю, может не настолько профессионально как Вы, но уж как умею. Вопрос к Вам как к Гуру, как netcat заставить выдавать те значения которые ему отправляет ардуино (сделать так чтобы он не пытался декодировать данные)
Написал код вот так вроде данные передает, только через какое то время падает(перестает передавать данные, хотя устройство пингуется ) Вопрос это косяк программы или ардуино не вытягивает??? Код (C++): #include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> // выход A0 int microphonePin = A0; // выбор пина для входа от микрофона int microphoneValue = 0; // переменная для хранения значения от микрофона int i = 0; // для счетчика считывания аналоговых покозаний String str = ""; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 33); unsigned int localPort = 8; // локальный порт, который будем прослушивать // буферы для получения и отправки данных char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // буфер, в котором будет храниться входящий пакет char ReplyBuffer[100]; // строка, которая будет отсылаться обратно // Создаем экземпляр класса EthernetUDP, чтобы отправлять и получать пакеты через UDP: EthernetUDP Udp; void setup() { // Запускаем Ethernet и UDP: Ethernet.begin(mac,ip); Udp.begin(localPort); Serial.begin(9600); Serial.print("My IP address: "); Serial.print(Ethernet.localIP()); } void loop() { // Если есть какие-либо доступные данные, считываем пакет: int packetSize = Udp.parsePacket(); if(packetSize) { IPAddress remote = Udp.remoteIP(); // Считываем пакет в packetBufffer: Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); Serial.println("Contents:"); // "Содержимое:" Serial.println(packetBuffer); //Serial.println (microphoneValue); Serial.println (ReplyBuffer); // Отсылаем ответ. Получатель – IP-адрес и порт, // от которых пришел полученный нами пакет: Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); // отправляем значение Udp.write(ReplyBuffer); Udp.endPacket(); str=""; } delay(10); mic(); } // записываем данные в буфер(массив) void mic(){ str= str+String(analogRead(microphonePin), DEC)+"|"; if(str.length()==100){ str.toCharArray(ReplyBuffer,100); } }