Миграция проектов на ПЛИС новых производителей

Побайтовый обмен с Arduino через шилд на базе ENC28j60

Новичок
 
Регистрация: 28.07.2015
Сообщений: 1
Репутация: 10
 
13.08.2015 18:41 #1
День добрый, есть система которая должна получать команды в байтовом формате по ethernet и при необходимости в байтовом же формате передавать какой-то ответ, опять же по ethernet.
В качестве базового котнроллера Arduino UNO, в качестве ethernet shield контроллер на базе ENC28j60.
Если делать на W5100, то там поставленная задача решается просто, например вот так

EthernetClient client = server.available();
if (client.available()>0)
{
serial_data=client.read();
if (serial_data==3)
server.write('1');

Но на руках есть именно ENC28j60. Так что комментарии типа забей и возьми W5100 не конструктивны
Для чипа ENC28j60 использовал разные библиотеки в итоге заработала только EherCard, взятая с github, причем старая версия от 2014 года. С остальными библиотеками столкнусля с ошибками на стадии компиляции примеров (среда arduino ide 1.6.5 с оф сайта) причина их не понятна, но не в этом суть.
От сетей я довольно далек поэтому после нескольких дней копания библиотеки и чтения форумов не смог ничего придумать на замену примера выше.
Почти все примеры имеют отношение к общению через веб. У меня задача другая, открываю какой-либо порт и из приложения кидаю команды, представляющие собой числа в hex объемом 1 байт, arduino их принимает, что-то делает и если надо отвечает через этот же порт в приложение каким-то числом в такой же форме.

Смотрел видео Осипова
https://www.youtube.com/watch?v=PPB2Xvubt4s
https://www.youtube.com/watch?v=RgJnYsTmM5A
но то что нужно я там не нашел

Я хочу забирать из ТСР пакета байт 0х0036, выделен черным.
Как мне казалось можно использовать конструкции как у Осипова типа

word len = ether.packetReceive();
word pos = ether.packetLoop(len);
if (pos){
Serial.println(pos);
bfill = ether.tcpOffset();
char *data = (char *) Ethernet::buffer + pos;
if (strncmp("T", data, 1) != 0) { //сравниваем первый значащий символ в полученном пакете
Serial.println('1');
}
else {Serial.println('2');}
}

Serial здесь для отладки стоят. В результате в мониторе пусто. то есть даже нет захода в первое условие.
Погонял через Wireshark скетч Осипова с выводом содержимого pos в монитор, получил следующую статистику, при нажатии кнопки на странице происходит отправка 10 ТСР пакетов, а в монитор выводится два раза число 54. После анализа содержимого переданных пакетов первая мысль pos - содержит первый байт передаваемых данных в пакете, так как пакеты с данными (их всего два из 10) содержали число "54" но по адресу 0х0038, так как по идее данные должны начинаться с адреса 0х0036, этот вариант был отвергнут, перевел адрес 0х0036 в десятичную систему получил искомое "54", то есть адрес первого байта полезных данных.
Начал эксперементировать с участком кода,приведенным выше и о чудо получил ответ, но опять странный. Ответ появляется только если я отправляю больше 8-ми байт данных. И похоже получил подтверждение что приходит в pos адрес первого байта полезных данных. Потому что в коде нет функции подтверждения о получении пакета и с ПК он шлется несколько раз, сколько отправит столько и сообщений в мониторе.
Пока писал это сообщение на часть вопросов уже сам нашел ответ, но не факт что правильный, поэтому небольшой итог
По функциям:

word len = ether.packetReceive(); //как описано в библиотеке копирует принятые данные в буфер и возвращает длину пакета данных

word pos = ether.packetLoop(len); //как описано в библиотеке анализирует полученные данные определенной длины, возвращает адрес смещения полезных данных в пакете или ноль, если ничего нет или служебные данные, как выяснилось также возвращает ноль если длина данных меньши восьми байт.

Погружаясь глубже в библиотеку нашел участок кода этой функции в файле tcpip.cpp

if (tcp_client_state==3 && len>0)
{ //TCP connection established so read data
if (client_tcp_result_cb) {
uint16_t tcpstart = TCP_DATA_START; // TCP_DATA_START is a formula
if (tcpstart>plen-8)
tcpstart = plen-8; // dummy but save
uint16_t save_len = len;
if (tcpstart+len>plen)
save_len = plen-tcpstart;
(*client_tcp_result_cb)((gPB[TCP_DST_PORT_L_P]>>5)&0x7,0,tcpstart,save_len); //Call TCP handler (callback) function

Мне кажется ответ про восемь байт скрыт где-то здесь, особые подозрения вызывает последняя строчка, но не могу понять что в ней происходит, кто-нибудь может подсказать? и вопрос вызывает tcpstart, как она вычисляется, формулу то я нашел, но что в ней происходит не очень понял:
TCP_DATA_START ((uint16_t)TCP_SRC_PORT_H_P+(gPB[TCP_HEADER_LEN_P]>>4)*4)

Ну и еще один вопрос как работать с функцией вывода bfill.emit_p(), как выбрать параметры чтобы отправить один байт? А также как отправить подтверждение о получении ТСР пакета, а то клиент кидает 6-7 пакетов в ожидании ответа, а потом разрывает соединение?

Заранее спасибо!
Оценка
В многообразии литиевых батареек и аккумуляторов нет какого-то универсального или идеального варианта. Выбирая тот или иной вариант для питания устройства, разработчику приходится оперировать множеством параметров, используя наиболее оптимальное их сочетание для каждого приложения. Разберем параметры для различных приложений.
Новичок
 
Регистрация: 14.06.2018
Сообщений: 112
Репутация: 17
18 51
15 15
 
14.10.2018 11:15 #2
В каждой библиотеке, где обмен ведется пакетами, должна быть функция flash - опорожение буфера до его заполнения.
xxx.writeOneByte (<...>); // запис в буфер, но нет еще передачи
xxx.flash (); // передача пакета, независимо насколько заполнен
Оценка
Гуру
 
Регистрация: 13.05.2006
Сообщений: 3,908
Репутация: 1247
1,234 65
61 33
 
14.10.2018 12:22 #3
Цитата:
flash
Может flush ?
Оценка
Ответ
Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход
Электронные компоненты. Бесплатная доставка по России
Часовой пояс GMT +3, время: 23:50.
Обратная связь РадиоЛоцман Вверх