Отправка данных на мк посредством HTTP

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Ответить
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Отправка данных на мк посредством HTTP

Сообщение DmitryR »

Добрый день, столкнулся с проблемой, надеюсь на вашу помощь. На мк стоит http сервер, необходимо со страницы браузера отправлять на него данные при помощи GET запросов. Пакет данных имеет фиксированные параметры: 16 чисел по 8 бит каждое.
Допустим забиваю данные от 0 до 15 и отправляю

Код: Выделить всё

  let TransmitBuffer = new Uint8Array(16);

  for (var i = 0; i < 16; i++)
  {
    TransmitBuffer[i] = i;
  }

  console.log(TransmitBuffer);

  // TRANSMIT
  let xhr = new XMLHttpRequest();
  xhr.open("GET", "work.html?c=" + TransmitBuffer + Math.random(), true);
  xhr.responseType = "arraybuffer";
В консоль выводится:
'Uint8Array']
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
11: 11
12: 12
13: 13
14: 14
15: 15
buffer: ArrayBuffer(16)
byteLength: 16
byteOffset: 0
length: 16
Symbol(Symbol.toStringTag): "Uint8Array"
[[Prototype]]: TypedArray

Сам пакет имеет вид (в Wireshark):
GET /work.html?c=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,150.888148996449402 HTTP/1.1\r\n

В конце 0.888... это рандомное число, чтобы пакеты не кешировались, насколько я понимаю.

Теперь принимаю на стороне мк (stm32):

Код: Выделить всё

		    	else if(strncmp((char const *)buf,"GET /work.html?c=",17)==0)
		    	{
		    		for(uint8_t i = 0; i < 16; i++)
		    		{
		    			EthReceiveBuffer[i] = buf[i+17];

		    			snprintf(SendStr, 50, "%d = %d\r\n", i, EthReceiveBuffer[i]);
		    			HAL_UART_Transmit(&H_USART_DEBUG, (uint8_t*)SendStr, strlen(SendStr), 100);
		    		}

		    		for(uint8_t i = 0; i < 16; i++)
		    		{
		    			EthReceiveBuffer[i] = buf[i+17] - '0';

		    			snprintf(SendStr, 50, "%d = %d\r\n", i, EthReceiveBuffer[i]);
		    			HAL_UART_Transmit(&H_USART_DEBUG, (uint8_t*)SendStr, strlen(SendStr), 100);
		    		}
		    	}
2 вида приема, но результат все равно один, по сути я принимаю (да и отправляю) строку вида 0,1,2,3...
Полученный результат в консоль:
0 = 48
1 = 44
2 = 49
3 = 44
4 = 50
5 = 44
6 = 51
7 = 44
8 = 52
9 = 44
10 = 53
11 = 44
12 = 54
13 = 44
14 = 55
15 = 44

0 = 0
1 = 252
2 = 1
3 = 252
4 = 2
5 = 252
6 = 3
7 = 252
8 = 4
9 = 252
10 = 5
11 = 252
12 = 6
13 = 252
14 = 7
15 = 252

Принимается число и запятая за ним, но запятую я еще могу убрать, я не могу принять число именно как 8 битное, т.е. если я отправлю число 15, то оно отравится и примется как 1 и 5. Число 100 будет как 1 и 0 и 0.

Как можно отправить и принять именно 8 битный массив, где бит, содержащий число 75 будет принят как 75, а не как 7 и 5?
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Отправка данных на мк посредством HTTP

Сообщение roman.com »

1.
я использую преобразование из 48 чисел по 8 бит каждое (т.е. 48 байт) в строку.

Код: Выделить всё

//////////////////////////////////////////////////////// TX: int > String '001001': 
TX_String = '';
for(xTX=0; xTX<48; xTX++) {
  if (TX_int[xTX] < 100){TX_String += '0';};
  if (TX_int[xTX] < 10){TX_String += '0';};
  TX_String += TX_int[xTX];
};
2.
а затем уже передаю строку.

Код: Выделить всё

//////////////////////////////////////////////////////// TX: Eth: 
var req = new XMLHttpRequest(); // AJAX 
  label_error.innerHTML = 'error: ' + 'Запрос...';  
  label_error_2.innerHTML = 'error: ' + 'Запрос...';  
  req.open('GET', ('http://'+TX_IP+':'+TX_port+'/'+ TX_String) ); // адрес + Data
  req.send(null); //передача (для GET -null) 
   
  req.onreadystatechange = function() { //обработчик событий:  
    if (req.readyState == 4) {  //4: DONE (Операция полностью завершена).      
	  if(req.status == 200) {   //200: ответ сервера: HTTP/1.1 200 OK        
	    //label_error.innerHTML = 'error: ' + 'Принято';  
	    //label_error_2.innerHTML = 'error: ' + 'Принято';  
		RX_len = req.response.length; //len int
	    RX_String = req.responseText; //текст ответа
		RX_Ethernet(); 
	  }
      else       
	  {
	    label_error.innerHTML = 'error: ' + 'Ошибка';  
	    label_error_2.innerHTML = 'error: ' + 'Ошибка';  
	  };
    };
  };
  
};//TX_Ethernet
////////////////////////////////////////////////////////////////////////////////
3.
на стороне мк (ATmega328) делаю обратное преобразование:

Код: Выделить всё

    for(xTX=0; xTX<48; xTX++) {
      TX_int[xTX] = (TX_int[x1TX]&0x0F)*100 + (TX_int[x1TX+1]&0x0F)*10 + (TX_int[x1TX+2]&0x0F); 
      if (TX_int[xTX] > 255) {TX_int[xTX] = 255;}; // MAX 255
      x1TX = x1TX + 3;
    };
4.
затем процесс повторяется в обратном порядке))

5.
рандомное число я не использую, потому что у меня шифрование (кэширование исключено).

в этой теме делал...
https://www.radiokot.ru/forum/viewtopic ... &start=220

в идеале надо преобразовывать и передавать не десятичные значения а шестнадцатиричные значения...
тогда строка будет меньше в полтора раза.
потом переделаю))
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Отправка данных на мк посредством HTTP

Сообщение DmitryR »

roman.com, Насколько я понимаю я не смогу сделать то, что хочу используя имеющиеся методы, а именно GET запросы. Т.е. в любом случае отправляться будет строка.
Я делал что-то похожее на Вашу идею, отправлял числа заведомо известной длины и на стороне мк собирал уже в 8 или 16 битное.
Допустим 16 битное число у которого максимально значение 9999. При отправке этого числа со значением допустим 450, добавляем до 4х знаков = 0450 и отправляем строкой, а на стороне мк формируем число:
num = buf[0] * 1000 + buf[1] * 100 + buf[2] * 10 + buf[3] = 0 * 1000 + 4 * 100 + 50 * 10 + 0.
Метод плох тем, что надо строго знать сколько чисел может занимать каждый параметр. Либо использовать разделение чисел в строке каким-либо символом. В целом при не сложном и однозначно определенном протоколе это делается очень просто.
Но идея с шестнадцетиричными значениями мне очень даже понравилась, надо будет реализовать, спасибо)
Ну и с рандомным числом разобраться, чтобы поменьше лишнего было. Хотя весь GET запрос занимает порядка 380 байт, при 16 байтах передаваемой информации, лишние несколько байт роли особой не играют
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Отправка данных на мк посредством HTTP

Сообщение roman.com »

1.
я все числа привожу к стандартным байтам...
16 битное число - это 2 байта.
значение 9999 это:
-десятичное значение 39 и 15
-или шестнадцатеричное значение 270F.

но 2 байта это максимум 65535:
-десятичное значение 255 и 255
-или шестнадцатеричное значение FFFF (строка меньше в полтора раза).

48 чисел по 8 бит каждое (т.е. 48 байт) это строка 144 символа (48 байт * 3 = 144 символа).

2.
не надо с рандомным числом разобраться, потому что по любому придётся делать шифрование... потому что в интернет нельзя ничего передавать без шифрования...))
а шифрование автоматом решает вопрос с рандомным числом.
Ответить

Вернуться в «Интеграция с ПК»