Передача из UART в SPI или I2C

khseal
Offline
Зарегистрирован: 15.01.2016

Реально ли написать код который будет передавать данные полученные из UART в SPI или I2C? Т.е. мост между UART и другой шиной.

Причем данные больших объемов около 200 кб. Теоритически это возможно, но практически как-то плохо себе представляю. 

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Реально.

MacSim
Offline
Зарегистрирован: 28.11.2012

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

а может и все три сразу? принял на один раздал на два.

khseal
Offline
Зарегистрирован: 15.01.2016

MacSim пишет:

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

а может и все три сразу? принял на один раздал на два.

Подскажите где этот пример искать. Поиском по форуму?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

здесь поищи: C:\Program Files\Arduino\hardware\arduino\avr\libraries

идея-то простая

c=Serial.read();
I2C.write(c);

c=I2C.read();
Serial.write(c);

 

khseal
Offline
Зарегистрирован: 15.01.2016

Ок, спасибо. Попробую отпишусь. 

khseal
Offline
Зарегистрирован: 15.01.2016

Написал вот такую простыню

char SerialData; 
#include "Wire.h"
void setup()
{


  Serial1.begin(115200);
//  while (!Serial1);             // Leonardo: wait for serial monitor
}


void loop()

{
          while (Serial1.available()==0) {             //Wait for user input
        }
        SerialData=Serial1.read(); 
        Wire.begin();
        Wire.beginTransmission('\x29');
        Wire.write(SerialData);
        Wire.endTransmission();

}

Мелкие данные отправляются без проблем. А вот когда плотный трафик ардуина похоже не успевает обрабатывать и пропускает данные. Можно что-то с этим сделать? Отправляю изображение на дисплей в итоге приходит одна треть данных =) 

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

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

А вот когда плотный трафик ардуина похоже не успевает обрабатывать и пропускает данные. Можно что-то с этим сделать?

можно - нужно проверять свободное место в буфере перед отправкой.

так понимаю Wire.requestFrom() нужно просить отсылать куда-то если что-то уже готово принять.

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

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

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

Эээ, не совсем понял как это реализовать.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Эээ, не совсем понял как это реализовать.

ну, у тебя есть

Wire.requestFrom()
Serial.available()
Serial.availableForWrite()
 
с ними нужно что-то делать
khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

ну, у тебя есть

Wire.requestFrom()
Serial.available()
Serial.availableForWrite()
 
с ними нужно что-то делать

Это я понял, но не понял как их реализовать правильно в коде. Т.е. пока алгоритм работы я не представляю. Ладно буду думать.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Это я понял, но не понял как их реализовать правильно в коде. Т.е. пока алгоритм работы я не представляю. Ладно буду думать.

я не знаю, как работает Wire и есть ли там вообще буфер...

а, с сериалом примерно так - не посылать, пока if (Serial.availableForWrite() > (t.length() + 1))

т.е. пока не освободится место в буфере для строки длиной + 1 символ

к примеру.

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

я не знаю, как работает Wire и есть ли там вообще буфер...

В интернете пишут что буфер около 32 байта, да и в библиотеке я нашел параметр установки буфера.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

В интернете пишут что буфер около 32 байта...

да, но нет аналогов

Serial.available()
Serial.availableForWrite()
 
но, зато есть Wire.requestFrom() 
 
блин, ну бери и читай про эти команды и думай, над условиями выполнения записи-чтения
khseal
Offline
Зарегистрирован: 15.01.2016

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

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

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

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

отправлял одним сериалом

Serial.write((byte*)&t,sizeof(t));

получал вторым сериалом и отправлял в USB

if (Serial.available()) {Serial.readBytes((char*)&t,sizeof(t));
if (DigiUSB.tx_remaining() > ((t.length() + 1)) { // проверка места в буфере USB для переменной длиной + x символ.
DigiUSB.print(t);
DigiUSB.print('\n');
}
}

без проверки свободного места в буфере USB данные терялись

Logik
Offline
Зарегистрирован: 05.08.2014

khseal пишет:

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

Здравая мысль. У Вас по UART данные сыпются на скорости 115200 а отправляются по I2C на 100000. И некоторая специфика синхронной шины - ожидание подтверждения. Потому данные валятся на контролер быстрей чем он их откидывает, разница в бухере наростает, пока не гавкнет. Варианты очевидны - понижать скорость UART, повышать I2C если периферия позволит или учить UART управлять источником данных, выдавая сигнал готовности приемника RS не зря кроме TxD, Rxd и GND имеет ещё кое какие линии.

khseal
Offline
Зарегистрирован: 15.01.2016

Logik пишет:

Здравая мысль. У Вас по UART данные сыпются на скорости 115200 а отправляются по I2C на 100000. И некоторая специфика синхронной шины - ожидание подтверждения. Потому данные валятся на контролер быстрей чем он их откидывает, разница в бухере наростает, пока не гавкнет. Варианты очевидны - понижать скорость UART, повышать I2C если периферия позволит или учить UART управлять источником данных, выдавая сигнал готовности приемника RS не зря кроме TxD, Rxd и GND имеет ещё кое какие линии.

Проверял на скорости 9600 все работает отлично но медленно, на скорости 57600 такой же затык как и на 115200. Про управление UART тоже думал, но в данном случае это невозможно.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Проверял на скорости 9600 все работает отлично но медленно, на скорости 57600 такой же затык как и на 115200. Про управление UART тоже думал, но в данном случае это невозможно.

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

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

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

Роутер на Openwrt > UART > Arduino > I2C > Display OLED.

Примерно такая последовательность данных. Вчера извращался по разному, но ничего не получилось. Т.к. мне кажется затык на приеме данных по UART.

Хотя можно забить и сделать колхоз и подключить дисплей параллельно по UART =)

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Роутер на Openwrt > UART > Arduino > I2C > Display OLED.

Примерно такая последовательность данных. Вчера извращался по разному, но ничего не получилось. Т.к. мне кажется затык на приеме данных по UART.

ну, я так понимаю, что пока Wire.available() > 0 нужно запрещать Serial.read()

ну, и конечно, учитывать скорости интерфейсов если у тебя UART быстрее интерфейса, в который ты передаёшь, то не скорость UART нужно лечить, а частоту опроса UART с учётом буфера принимающего медленного интерфейса.

т.е. что-то прилетело в буфер UART - жди пока обработается приём в медленный интерфейс.

*попытки уменьшить скорость передачи в UART смысла не имеют, т.к у тебя по любому скорость передачи определяется самым медленным интерфейсом в цепочке передачи.

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

ну, я так понимаю, что пока Wire.available() > 0 нужно запрещать Serial.read()

ну, и конечно, учитывать скорости интерфейсов если у тебя UART быстрее интерфейса, в который ты передаёшь, то не скорость UART нужно лечить, а частоту опроса UART с учётом буфера принимающего медленного интерфейса.

т.е. что-то прилетело в буфер UART - жди пока обработается приём в медленный интерфейс.

*попытки уменьшить скорость передачи в UART смысла не имеют, т.к у тебя по любому скорость передачи определяется самым медленным интерфейсом в цепочке передачи.

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

Мне кажется Logik прав, тут нужен сигнал готовности приемника, но в данном железе это не реально организовать. Либо как-то со стороны роутера хитро, организовывать передачу надо с определенным ожиданием.

Logik
Offline
Зарегистрирован: 05.08.2014

Клапауций 322 пишет:

ну, я так понимаю, что пока Wire.available() > 0 нужно запрещать Serial.read()

И что с того что не прочитаем данные, они от этого не перестанут сыпатся на ардуино, будут пропуски.

Клапауций 322 пишет:

попытки уменьшить скорость передачи в UART смысла не имеют, т.к у тебя по любому скорость передачи определяется самым медленным интерфейсом в цепочке передачи.

Еще как имеют. Если скорость передачи в UART станет менше скорости передачи  самым медленным интерфейсом в цепочке передачи, то все работает. Что и наблюдается при 9600. 

А вот факт завала на 57600 тревожен. Возможно работа по i2c организована плохо, и реальная скорость существенно ниже 100000. Например для каждого блока данных происходит заново передача адреса устройства, команды и прочей фигни, вместо того, чтоб передать это раз для первого блока а затем только данные докидывать.

Попробуйте оценить используемый размер буфера Serial, например так (код не проверял

byte MaxAvl;

void setup(){
....
MaxAvl=0;}

void loop() {
...
byte A=Serial.available();
if(A>MaxAvl) MaxAvl=A;
....
//где-то после завершения обмена, при простое
Serial.println(A); // или на экран, или еще куда чтоб посмотреть

}

)

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

У меня олед отлично принимает на 800кГц, по паспорту у него 400кГц, так что Вам можно пробовать повышать. 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

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

да, не Дуино не успел принять, а роутер не смог отправить до конца, т.к. ты Дуино, не дождавшись окончания отправки, начинаешь делать что-то другое - поэтому у тебя и складывается впечатление, что Дуино не успевает.

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

khseal
Offline
Зарегистрирован: 15.01.2016

Logik пишет:

 

Еще как имеют. Если скорость передачи в UART станет менше скорости передачи  самым медленным интерфейсом в цепочке передачи, то все работает. Что и наблюдается при 9600. 

А вот факт завала на 57600 тревожен. Возможно работа по i2c организована плохо, и реальная скорость существенно ниже 100000. Например для каждого блока данных происходит заново передача адреса устройства, команды и прочей фигни, вместо того, чтоб передать это раз для первого блока а затем только данные докидывать.

Попробуйте оценить используемый размер буфера Serial, например так (код не проверял

byte MaxAvl;

void setup(){
....
MaxAvl=0;}

void loop() {
...
byte A=Serial.available();
if(A>MaxAvl) MaxAvl=A;
....
//где-то после завершения обмена, при простое
Serial.println(A); // или на экран, или еще куда чтоб посмотреть

}

)

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

Я кстати пробовал изменить запись в Wire. Пытался писать с помощью string, но тогда все почему-то работает еще медленней. Вот может проблема в том что данные надо докидывать, а не постоянно дергать Wire инициализацией.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Logik пишет:

И что с того что не прочитаем данные, они от этого не перестанут сыпатся на ардуино, будут пропуски.

если не прочитаем, что буфер записи UART роутера не очистится и дальнейшая передача будет заблокирована буфером.

что и наблюдаем - при неуправляемом Serial.read() на стороне Дуино

приняли быстрым интерфейсом, не упели отправить в медленный интерфейс, делаем снова Serial.read(), затирая ещё не оправленное

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

да, не Дуино не успел принять, а роутер не смог отправить до конца, т.к. ты Дуино, не дождавшись окончания отправки, начинаешь делать что-то другое - поэтому у тебя и складывается впечатление, что Дуино не успевает.

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

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

Думаю, у меня сейчас данные в ком порт отправляются как данные UDP =)

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Роутер отошлет все без проблем и не будет ждать пока буфер очиститься чтением.

сомнительно мне это.

Logik
Offline
Зарегистрирован: 05.08.2014

Клапауций 322 пишет:

да, не Дуино не успел принять, а роутер не смог отправить до конца, т.к. ты Дуино, не дождавшись окончания отправки, начинаешь делать что-то другое - поэтому у тебя и складывается впечатление, что Дуино не успевает.

Бред.  Роутер отправит и до конца даже если Дуню из посылки не достали. Ему плевать слушает его кто, успевает ли принять и т.д. RS не полный, только Txd,  RxD и GND. 

 

Как роутер узнает, что пора начинать

Клапауций 322 пишет:
 ждать, пока этот буфер очистьтся чтением из него UART Дуино, и так далее.

Если нет управляющих сигналов? Для полного RS такое работает.

Если действительно затык на i2c и нужна высокая скорость, то пока этот затык не ликвидировать скорости не будет. 

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

 

khseal пишет:

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

Ни как. Почти никак. Можна типа обратно отправлять подтверждения на роутер по Serial. Типа роутер плюнул 32 байта, дуня прожевал и в Serial выдала - давай еще 32 байта, если есть. Но реальная скорость при этом упадет и сильно.

khseal
Offline
Зарегистрирован: 15.01.2016

Logik пишет:

Ни как. Почти никак. Можна типа обратно отправлять подтверждения на роутер по Serial. Типа роутер плюнул 32 байта, дуня прожевал и в Serial выдала - давай еще 32 байта, если есть. Но реальная скорость при этом упадет и сильно.

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

Сегодня вечером попробую ваш код для отслеживания буфера.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Logik пишет:

Бред.  Роутер отправит и до конца даже если Дуню из посылки не достали. Ему плевать слушает его кто, успевает ли принять и т.д. RS не полный, только Txd,  RxD и GND. 

до какого "конца"?

конец случится после того как полностью заполнен буфер UART роутера, затем ты достаёшь свою Дуино из посылки и успешно делаешь Serial.read() буфера UART роутера в буфер приёма UART Дуино - где ты эту инфу теряешь в недрах Дуино, это твои личные проблемы.

Logik
Offline
Зарегистрирован: 05.08.2014

Клапауций 322 пишет:

до какого "конца"?

До самого.

Клапауций 322 пишет:

конец случится после того как полностью заполнен буфер UART роутера, затем ты достаёшь свою Дуино из посылки и успешно делаешь Serial.read() буфера UART роутера в буфер приёма UART Дуино - где ты эту инфу теряешь в недрах Дуино, это твои личные проблемы.

Кончай тупить. RS не полный!!! Роутер из своего буфера сразу начнет передавать не зная слушает его кто или нет. Он остановится только после передачи всего, что у него есть. Ты рассказываеш про полный RS, с RTS, CTS и тд. А их нет!!!! RS не полный!!!

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Logik пишет:

Кончай тупить. RS не полный!!! Роутер из своего буфера сразу начнет передавать не зная слушает его кто или нет. Он остановится только после передачи всего, что у него есть. Ты рассказываеш про полный RS, с RTS, CTS и тд. А их нет!!!! RS не полный!!!

да, кто тупит? это ты утверждаешь, что UART Дуино работает только на скорости UART 9600 - а, всё, что выше Дуино, якобы "не успевает" принимать.

я утверждаю, что успевает - это ТС тупит, что сериал нужно опрашивать со скоростью, пропорциональной скорости передачи данных в медленный интерфейс, требуется программная синхронизация чтение_из_UART-запись_в_I2C

Logik
Offline
Зарегистрирован: 05.08.2014

Клапауций 322 пишет:

это ты утверждаешь, что UART Дуино работает только на скорости UART 9600 - а, всё, что выше Дуино, якобы "не успевает" принимать.

Это факт установленный опытным путем в данной ситуации http://arduino.ru/forum/programmirovanie/peredacha-iz-uart-v-spi-ili-i2c#comment-163753 Читать ответы полезно.

Клапауций 322 пишет:

я утверждаю, что успевает - это ТС тупит, что сериал нужно опрашивать со скоростью, пропорциональной скорости передачи данных в медленный интерфейс, требуется программная синхронизация чтение_из_UART-запись_в_I2C

Пропорционально, коллинеарно.. В бухер конечного размера данные поступают на скорости 115200 а извлекаются на 100000 (очень оптимистическая оценка). Чем закончится опыт если его проводить достаточно долго? Вот это переполнение буфера и называют "дуня не успевает".  Надеюсь к вопросу "роутер остановится и будет ждать" возвращатся не будем.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Logik пишет:

Надеюсь к вопросу "роутер остановится и будет ждать" возвращатся не будем.

будем - будем читать логи ОпенВРТ, что он пишет при отправке UARTом в пустоту.

 

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

будем - будем читать логи ОпенВРТ, что он пишет при отправке UARTом в пустоту.

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

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

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

не нужно мне ничего советовать - это у тебя что-то не получается и советы необходимы тебе.

я пытаюсь до тебя донести, что у тебе не нужно начинать чтение из сериала, пока ты не обработал прошлый результат чтения

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

не нужно мне ничего советовать - это у тебя что-то не получается и советы необходимы тебе.

я пытаюсь до тебя донести, что у тебе не нужно начинать чтение из сериала, пока ты не обработал прошлый результат чтения

А вам пытаются донести два человека что все работает совсем не так. К сожалению сколько не пишу на форумах, мало полезных советов дают по специфическим задачам. В итоге еще приходится другим объяснять как все работает на самом деле, а они еще не верят =( Видео снимать с опровержением и осциллографом лень. 

А то что у меня не получается это уже другой вопрос, в программной части сразу скажу что я не силен, но у меня сразу возникли сомнения по работоспособности данного мероприятия на высоких скоростях. Но как работает UART я прекрасно представляю =)

Цитата:

Пропорционально, коллинеарно.. В бухер конечного размера данные поступают на скорости 115200 а извлекаются на 100000 (очень оптимистическая оценка). Чем закончится опыт если его проводить достаточно долго? Вот это переполнение буфера и называют "дуня не успевает".  Надеюсь к вопросу "роутер остановится и будет ждать" возвращатся не будем.

Возник другой вопрос а умеет ли ардуина выше 100000 по i2c ? Надо попробовать т.к. дисплей кажется умеет даже 200000. Это проблему не решит я думаю, но проверить интересно.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

А вам пытаются донести два человека что все работает совсем не так.

ок. а, почему у меня работает так, как мне хочется?

смотри - пример передачи данных из дуино в медленный интерфейс.

без 9-й строки -всё так как и у тебя: дуино "не успевает".

теперь вопрос: так, кто не успевает? напиши подобное для сериала и промедитируй на суть процесса.


#include <DigiUSB.h>

void setup() {DigiUSB.begin();}

void loop() {

static String b = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF11111111112222222222333333333344444444445555555555666666666677777"; // объявление переменной строки.

if (DigiUSB.tx_remaining() > (b.length() + 1)) { // проверка места в буфере USB для строки длиной + 1 символ.

DigiUSB.print(b);
DigiUSB.print('\n');

}

DigiUSB.delay(1);

}

 

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

ок. а, почему у меня работает так, как мне хочется?

У вас не голый ком порт, с этого надо начать. У вас же USB прослойка, возможно у вас полноценный COM порт эмулируется со всеми управляющими сигналами. Плюс у вас дополнительная библиотека используется, которая за собой тянет еще кучу других библиотек. Попробуйте такое провернуть на чистом COM порту без эмуляции в USB.Где всего три провода...

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

Плюс я еще понимаю почему когда работает с ардуиной по USB  в опенврт порт надо инициализировать во такой строкой

stty -F /dev/ttyACM0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

В этой строке как раз и указывается работа с управляющими сигналами которых у меня нет.

А у меня инициализация порта происходит приблизительно так

stty -F /dev/ttyATH0 raw speed 115200

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

 

Я вот думал, подключить к OpenWRT ардуину по усб как сделали вы, но для леонардо похоже нет драйверов для роутера, чтобы он опознал ее как устройство с ком портом. Плюс у меня напряженка с USB портами в роутере, хотя надо рассмотреть этот вариант. Может быть где-нибудь нарою исходники драйвера и соберу под свой роутер.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

У вас не голый ком порт, с этого надо начать. У вас же USB прослойка, возможно у вас полноценный COM порт эмулируется со всеми управляющими сигналами. Плюс у вас дополнительная библиотека используется, которая за собой тянет еще кучу других библиотек. Попробуйте такое провернуть на чистом COM порту без эмуляции в USB.Где всего три провода...

ну, к чему эта демагогия  - возьми и проверь, получится ли у тебя...



void setup() {Serial.begin(115200);}

void loop() {

static String b = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF11111111112222222222333333333344444444445555555555666666666677777"; // объявление переменной строки.

if (Serial.availableForWrite() > (b.length() + 1)) {

Serial.print(b);
Serial.print('\n');

}

}

khseal пишет:

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

у тебя аналогично - у тебя на стороне дуино сом-порт отправляет в вире.

khseal пишет:

Я вот думал, подключить к OpenWRT ардуину по усб как сделали вы, но для леонардо похоже нет драйверов для роутера, чтобы он опознал ее как устройство с ком портом. Плюс у меня напряженка с USB портами в роутере, хотя надо рассмотреть этот вариант. Может быть где-нибудь нарою исходники драйвера и соберу под свой роутер.

ну, подожди - сколько проводов к UART контроллера Дуино идёт от преобразователя USB-UART?

два RX и TX или больше?

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

ну, подожди - сколько проводов к UART контроллера Дуино идёт от преобразователя USB-UART?

два RX и TX или больше?

Весь цимус в том что у меня нет никаких преобразователей в данной конфигурации. Я работаю с хардварными UART портами как на стороне роутера так и на стороне ардуины.

Есть только три провода Rx и TX и общий. И то можно подключать только два провода для отправки данных только на ардуину...

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

Весь цимус в том что у меня нет никаких преобразователей в данной конфигурации. Я работаю с хардварными UART портами как на стороне роутера так и на стороне ардуины.

Есть только три провода Rx и TX и общий. И то можно подключать только два провода для отправки данных только на ардуину...

ок. а, с преобразователем цимус в чём, если преобразователь соединён с контроллером двумя проводами?(Rx и TX и общий.)

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

ок. а, с преобразователем цимус в чём, если преобразователь соединён с контроллером двумя проводами?(Rx и TX и общий.)

Да преобразователем цимуса тоже нет, т.е. по трем проводам так же будет работать. У Леонардо преобразователь в самом микроконтроллере, думаю там полный фарш эмуляции ком порта. У вас думаю преобразователь подключен не по трем проводам к uart, а либо тоже встроенный в МК либо подключен через SPI.

Вот пример на этой картинке

https://www.arduino.cc/en/uploads/Guide/ArduinoProFTDIBreakout.jpg

Тут далеко не три провода. А есть еще и управляющие сигналы, видно что как минимум есть RTS =)

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

У вас думаю преобразователь подключен не по трем проводам к uart, а либо тоже встроенный в МК либо подключен через SPI.

начинает раздражать...

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

*если тебе интересно, то у меня два контроллера: в один входит интерфейс V-USB из него же выходит UART во второй контроллер. т.к. скорости интерфейсов разные, то передача данных V-USB->UART->UART и обратно синхронизируется программно по условию свободного места в буфере отправки.

khseal
Offline
Зарегистрирован: 15.01.2016

Клапауций 322 пишет:

начинает раздражать...

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

*если тебе интересно, то у меня два контроллера: в один входит интерфейс V-USB из него же выходит UART во второй контроллер. т.к. скорости интерфейсов разные, то передача данных V-USB->UART->UART и обратно синхронизируется программно по условию свободного места в буфере отправки.

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

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

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

khseal пишет:

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

ок. а, у тебя на каком уровне подключены?

у меня аналогичная конфигурация - быстрый дуино желает лупить данные в медленный интерфейс.

khseal пишет:

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

а, у меня где обратная связь?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

khseal пишет:

Возник другой вопрос а умеет ли ардуина выше 100000 по i2c ?

У меня со всеми устройствами (другая Ардуина, OLED-дисплей, вняшняя EEPROM, акселерометр, гироскоп, компас) работает на 400000.

И еще хочу вставить реплику по поводу оптимального протокола. Насколько я помню, у I2C в Ардуино буфер 32 байта. ПРи этом никуда не денешься от адреса устройства, т е реальная длина пакета данных не может быть больше 31 байта. При этом по факту (неоднократно сталкивался с таким кодом) зачастую длина пакета данных составляет 1 байт. При этом скорсть передачи примернор втрое ниже, чем могла бы быть.

Logik
Offline
Зарегистрирован: 05.08.2014

andriano пишет:

У меня со всеми устройствами (другая Ардуина, OLED-дисплей, вняшняя EEPROM, акселерометр, гироскоп, компас) работает на 400000.

А чего им не работать на 400кГц, если у них в спеке так и написано. Интересней что некоторые (а может и все?) вполне тянут около 800кГц, а эта нестандартная скорость интересна тем, что она получается при програмной реализации I2C простым ногодрыгом. Получается очень просто и удобно, передача без буфера, на любых ногах контроллера.

andriano пишет:

ПРи этом никуда не денешься от адреса устройства, т е реальная длина пакета данных не может быть больше 31 байта. 

Нет. Можна адресок передать только в первом блоке. По завершению передачи из буфера не делать стоп шине. Потом снова заполнять буфер и следующие данные пойдут без передачи адреса, так, как и не было паузы. 

andriano пишет:

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

Да. К сожалению криворукус вульгарис не в красной книге. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Logik пишет:

Нет. Можна адресок передать только в первом блоке. По завершению передачи из буфера не делать стоп шине. Потом снова заполнять буфер и следующие данные пойдут без передачи адреса, так, как и не было паузы. 

Здорово.

А я по недомыслию передавал пакеты длиной 17 байт (нужна была степень двойки, поэтому 1+16).

Кстати, откуда уверенность, что "не было паузы"? Я так понимаю, что начинать заполнять буфер по новой можно только после того, как он будет полностью передан. И, кстати, передача из буфера осуществляется не по команде завершения?