Быстрая передача данных через comport на arduino pro

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

Новичок в ардуино, столкнулся с проблемой передачи данных на ПК через usb на ардуино про.

Использую эту библиотеку для АЦП https://github.com/adienakhmad/ADS1256

Имею модуль АЦП ADS1256, с него читаю два канала в переменные типа float с частотой 15000SPS

На деле при ипсользовании передачи через Serial.print имею около 500SPS. Отключал передачу переменных, делал счётчик, который считал за какое время переменные перезаписываются тысячу раз, получил то, что за секунду они перезаписываются честные 15000 раз. Из этого делаю вывод, что по какой-то причине не хватает пропускной способности com порта. Установка баудрейта в 115200 не помогает. 

Есть ли возможность как-то передавать все моменты считывания на пк через usb? Возможно ли использовать какой-то буфер для передачи данных? Например, писать данные с АЦП на SD карту, а потом по окончанию измерений медленно считывать с нее обратно и передавать по usb? Или использовать какой-то spi-usb конвертер для соединения ардуинки и пк с большой пропускной способнотью? Или какие-то еще варианты?


#include <ADS1256.h>
#include <SPI.h>
float clockMHZ = 7.68; 
float vRef = 2.5;
ADS1256 adc(clockMHZ,vRef,false); 
int row = 0; //Номер строки
float sensor1, sensor2, current, voltage;

void setup()
{ Serial.begin(38400);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,Voltage, Current");
  adc.begin(ADS1256_DRATE_15000SPS,ADS1256_GAIN_8,false); 
  adc.setChannel(4,5);
  adc.waitDRDY();            //Ожидание готовности АЦП
  adc.sendCommand(SELFCAL);  //самокалибровка АЦП
}

void loop()
{   
  adc.waitDRDY(); //Ожидание готовности АЦП
  adc.setChannel(4,5);   
  sensor2 = adc.readCurrentChannel();
  adc.waitDRDY(); //Ожидание готовности АЦП
  adc.setChannel(2,3); 
  sensor1 = adc.readCurrentChannel(); 
  current = (sensor2/0.08);
  voltage = (sensor1*12.5);
  row ++;
  Serial.print("DATA,TIME,");
  Serial.print(voltage,3);
  Serial.print(",");
 Serial.println(current,6);
  
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Вы, простите, считать умеете? Баудрейт 38400 - это примерно 4000 символов в секунду. А теперь смотрим в код - на каждый отсчет вы выводите в сериал 25-30 символов (строки 30-33). Так чего ж вы хотите тогда, считайте
4000 символов в сек / 25 = порядка 150
Вот эти 150отсчетов в секунду вы и можете вывести на печать. При скорости порта 115200 - в три раза больше, как раз и выходит те 500, что вы намеряли

b707
Offline
Зарегистрирован: 26.05.2017

Super_indian_co - а вообще, ваш код повергает меня в недоумение.

1. Вы сами понимаете, что вам не хватает скорости порта - и почему-то ставите 38400 вместо 115200, снижая скорость передачи втрое ??

2. Опять же, сами понимаете что скорости мало - и сами же передаете через порт кучу мусора, все эти "DATA,TIME," и числа в виде строчек - что понижает скорость передачи еще втрое.

Ну а что касается идеи "не передавать сразу. а сначала писать в буфер" - в принципе, это правильно. Только учитывайте, что для записи данных на скорости 15000 SPS надо очень много памяти, которой в ардуино нет. В стандартной Уно всего 2К оперативки. Если писать в память два значения float с частотой 15 КГц - всей оперативки хватит всего на 1/60 секунды

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Сдается мне, что он в Эксель гонит данные для построения диаграммы.

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:
Сдается мне, что он в Эксель гонит данные для построения диаграммы.

это не избавляет от необходимости думать головой :)

Особенно прикольно строчку @DATE@  обновлять 15к раз в секунду :)

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Если Вам надо быстро - так не гоните текст, кроме того передавайте sensor1 и sensor2, причем не float, а uint_16, а все преобразования делайте на принимающей стороне.

b707
Offline
Зарегистрирован: 26.05.2017

mykaida пишет:

Если Вам надо быстро - так не гоните текст, кроме того передавайте sensor1 и sensor2, причем не float, а uint_16, а все преобразования делайте на принимающей стороне.

Как не ухищряйся, а 15000 SPS через UART не передать. Даже для передачи в uint16 потребуется канал порядка 1 Мбод с учетом накладных расходов

sadman41
Offline
Зарегистрирован: 19.10.2016

Текст - это не текст, а макрос таймштампа, без них никак. Причем, если это то, о чем я думаю, то никакие буфера и SD-карты не помогут.
Не знаю, насколько ускорит работу передача uint16 вместо float, но совет дельный

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

два значения по 16 бит = 4 байта, пусть еще один контрольный - 5. !0 тактов на байт, выходит 50 тактов. 15 тыс. выборок в сек. 750 Кбит/сек. Что автор подразумевает под "Ардуино про" я не понимаю. "Про мини" или "про микро" или просто "про"? Не суть важно, даже самый дешевый вариант с CH340 USB-UART конвертором тянет до 1000000. 38400, конечно, было очень смешно!!! ;)))

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:
Текст - это не текст, а макрос таймштампа

тогда там еще больше символов. Хотя макрос вроде _DATE_ должен быть...

Цитата:
без них никак.

почему? нафига дата на каждой точке - если на графике всего несколько секунд?

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

Добрый вечер, почему буфер идея не очень?

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

sadman41 пишет:
Сдается мне, что он в Эксель гонит данные для построения диаграммы.

Так и есть

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

b707 пишет:

Super_indian_co - а вообще, ваш код повергает меня в недоумение.

1. Вы сами понимаете, что вам не хватает скорости порта - и почему-то ставите 38400 вместо 115200, снижая скорость передачи втрое ??

2. Опять же, сами понимаете что скорости мало - и сами же передаете через порт кучу мусора, все эти "DATA,TIME," и числа в виде строчек - что понижает скорость передачи еще втрое.

Ну а что касается идеи "не передавать сразу. а сначала писать в буфер" - в принципе, это правильно. Только учитывайте, что для записи данных на скорости 15000 SPS надо очень много памяти, которой в ардуино нет. В стандартной Уно всего 2К оперативки. Если писать в память два значения float с частотой 15 КГц - всей оперативки хватит всего на 1/60 секунды

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

1. Случайно в примере кода не то значение оставил.

2. От мусора можно отказаться, не критично, но на деле видимого сильного эффекта не давало.

Как думаете,  получится ли организовать рабочий буфер через SD карту?

b707
Offline
Зарегистрирован: 26.05.2017

Super_indian_coder пишет:

Как думаете,  получится ли организовать рабочий буфер через SD карту?

Вы так и не ответили, какая скорость записи вам нужна и какой период писать.

15000 SPS для Sd по ардуиной - это очень непросто, не уверен, что получится

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

sadman41 пишет:
Текст - это не текст, а макрос таймштампа

тогда там еще больше символов. Хотя макрос вроде _DATE_ должен быть...

Надстройка Экселя PLX-DAQ, получив слово 'TIME', сует в ячейку таблицы экселя ПК-шное время прихода данных. Соответственно, числа, последовавшие за этим макросом, хоть как-то привязаны к конкретной временной точке. С 'DATE' точно так же.

К сожалению, я не имею ни малейшего понятия о смысловом аспекте диаграммы, поэтому не в курсе - нужна там дата или нет. Для PLX эти макросы имеют значение.

sadman41
Offline
Зарегистрирован: 19.10.2016

Super_indian_coder пишет:

Добрый вечер, почему буфер идея не очень?


Потому что таймштампы потеряют смысл.

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

b707 пишет:

Super_indian_coder пишет:

Как думаете,  получится ли организовать рабочий буфер через SD карту?

Вы так и не ответили, какая скорость записи вам нужна и какой период писать.

15000 SPS для Sd по ардуиной - это очень непросто, не уверен, что получится

Необходимо как раз 15000SPS. Период записи не более трех секунд.

Super_indian_coder
Offline
Зарегистрирован: 26.03.2021

sadman41 пишет:
Super_indian_coder пишет:

Добрый вечер, почему буфер идея не очень?

Потому что таймштампы потеряют смысл.

От них несложно отказаться в моем проекте

b707
Offline
Зарегистрирован: 26.05.2017

Super_indian_coder пишет:

Необходимо как раз 15000SPS. Период записи не более трех секунд.

Ну считайте.

 Если перевести результаты в uint16 (с потерей точности), то 15000SPS - это 60 Кбайт данных в секунду. В ардуине такой обьем девать просто некуда, единственный варинт - сразу  куда-то передавать. Соответственно, нужен поток 60*8 = 480 КБит/сек

В самых лучших примерах, что я нашел , запись на СД-карту работала со скоростью 800-1000 кБит/сек. Вроде бы хватает - но учитывайте, что процесс этот на ардуине займет все ресурсы платы и на считывание данных с датчика времени просто не останется. Кроме того, учитывайте замечание Садман41 о том, что вы потеряете метки времени.

Ровно такой же расклад будет, если взять, например, микросхемы внешней памяти, подключаемые по SPI - например типа W25Q

 

Честно говоря, я бы на вашем месте сменил МК на СТМ32. У него и ядро побыыстрее, и , главное - на нем есть DMA - то есть возможность писать данные из памяти на внешний носитель асинхронно, не занимая процессор. Там ваша задачка выглядит реальнее, а на ардуине, кмк, шансов мало.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

А если сделать промежуточный буфер например 32кБ в EEPROM и по заполнению скидывать его на SD одной сессией? Должно всяко быстрее получиться чем потоком писать короткие сессии сразу на SD. Не здаю, потянет ли атмега сразу три процесса в параллели, но STM или ESP32 вполне должны справиться

Можно взять кастомную ESP с кучей PSRAM

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Super_indian_coder пишет:

Необходимо как раз 15000SPS. Период записи не более трех секунд.

Родное сердце! Ну я ж посчитал! Давай еще раз.

Ты знаешь, что такое биты и байты? Давай я подробно посчитаю, теперь для float.

Ты получаешь два float показания, 15000 раз в секунду, так?

Во float 32 бита = 4 байта, так?

Порт настроен на протокол 8n1, так?

То есть на один байт идут: стартовый бит + 8 бит данных + стоп бит = 10 бит, так?

Итого нужно передать 15000sps * 2сенора * 4байта *10бит = 1 200 000 бит в секунду. Один миллион двести тысяч бит в секунду. Это НЕ ТЕКСТОМ, БЕЗ МУСОРА в виде date|time и прочего!

===================

Еще раз повторю, что в зависимости от старости компа и типа платы, есть пределы на скорость передачи, но 1500000 (миллион пятьсот тысяч) выставлять можно. Какие, в жопу, 38400 или 115200??? В ардуино хранить 120Кбайт негде. Внешняя память тебя не спасет, потому, что SPI занят, а I2C не работает на скорости в 1.2 Мбит/сек.

Таким образом ровно два выхода:

1. работай на том, что есть и прими свои 120К (за секунду, или 360К за 3сек) данных в комп. В этом нет никаких трудностей. Напиши программу на Питоне, C# или на "чистом" С, что тебе ближе, или закажи её тут на форуме, которая примет несчастные 360К данных и сохранит их в том формате, который тебе дальше удобно обработать в том, в чем ты там их обрабатываешь.

2. Смени контроллер на STM32 в нем 2 SPI и можешь тогда использовать какую-то внешнюю память для буфера. Или подбери контроллер уже с достаточной памятью. Кстати можно на Распберри или Оранж пи принимать по SPI без проблем. И уж там памяти точно достаточно для всей этой радости.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

и в догонку: есть более скростные специализированные USB-SPI конвертеры, например на MCP2210, с которыми ты без Ардуины подключишь АЦП прямо к компу.

Как видишь есть много решений твоей задачи.

sadman41
Offline
Зарегистрирован: 19.10.2016

Eeprom достаточно медленная, в любом случае будут затыки в момент записи на SD. Лишнее звено быстродействия не добавит.
Пытаясь остаться в концепции применения 328го МК, необходимо искать какую-нить SPI-RAM. Но дешевле, наверное, будет перейти на другой МК, который имеет больше ресурсов - мне кажется, что слишком дорогое решение получится на 328м.

ESP - неплохой вариант из широко доступных, жаль что невозможно ей управлять на уровне железа. Там ведь на фоне крутятся задачи какие-то ещё. Есть вероятность, что одной из них срочно будет необходимо отработать в период оцифровки.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

sadman41 пишет:
Eeprom достаточно медленная, в любом случае будут затыки в момент записи на SD. Лишнее звено быстродействия не добавит. Пытаясь остаться в концепции применения 328го МК, необходимо искать какую-нить SPI-RAM. Но дешевле, наверное, будет перейти на другой МК, который имеет больше ресурсов - мне кажется, что слишком дорогое решение получится на 328м. ESP - неплохой вариант из широко доступных, жаль что невозможно ей управлять на уровне железа. Там ведь на фоне крутятся задачи какие-то ещё. Есть вероятность, что одной из них срочно будет необходимо отработать в период оцифровки.

 

У него на SPI висит эта самая микросхема АЦП, переключаться "туда-сюда" - не успеет. По SPI уже поток почти в мегабит идет от АЦП.

sadman41
Offline
Зарегистрирован: 19.10.2016

Вполне может быть, спорить не стану, в математику не вдавался.
На пальцах только прикинул - какое направление имеет потенциал разработки.

Похоже, что приведенный выше переходник со SPI на USB с каким-нибудь самописным граббером данных выглядит более привлекательно.

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

sadman41 пишет:
Потому что мне помнится, что PLX тоже не работает на мегабитных скоростях - у него какие-то стандартные, несколько штук на выбор.

Напомни, вас ист дас "PLX"? ;)) Я пропустил часть переписки. Сорри.

sadman41
Offline
Зарегистрирован: 19.10.2016

PLX-DAQ is a Parallax microcontroller data acquisition add-on tool for Microsoft Excel. Any of our microcontrollers connected to any sensor and the serial port of a PC can now send data directly into Excel. PLX-DAQ has the following features:

   - Plot or graph data as it arrives in real-time using Microsoft Excel 

   - Record up to 26 columns of data

   - Mark data with real-time (hh:mm:ss) or seconds since reset

   - Read/Write any cell on a worksheet

   - Read/Set any of 4 checkboxes on control the interface

   - Example code for the BS2, SX (SX/B) and Propeller available

   - Baud rates up to 128K

   - Supports Com1-15

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

sadman41 пишет:

PLX-DAQ is a Parallax microcontroller data acquisition add-on tool for Microsoft Excel.

Понял. Не годится, тут нужно на скорости в 1500000 принимать, а он такого не умеет. Нужно писать свою программу коммуникации с АЦП. Как я выше написал уже.

b707
Offline
Зарегистрирован: 26.05.2017

Стм с двумя SPI . По одной через DMA принимаем, по другой опять ч ДМА отдаем

OK0
Offline
Зарегистрирован: 06.03.2020

А 328pb не справится? 2 SPI, 2 Serial, 32 мГц http://arduino.ru/forum/obshchii/vse-pro-atmega328pb-0

sadman41
Offline
Зарегистрирован: 19.10.2016

Справится, наверное, если запись в буфер будет без пенальти происходить. В случае с SD я в этом не уверен.