Парсинг ответа от видеокамеры. Разбираем String

forfrends
Offline
Зарегистрирован: 24.02.2015

Всем привет! Делаю пульт для камеры GoPro Hero3+ Black. Библиотеку брал здесь: https://github.com/aster94/GoProControl

Описание работы с камерой читал здесь: https://github.com/KonradIT/goprowifihack

Команды на управление передаю без проблем, камера их принимает, и делает то что нужно. Но хотелось бы на пульте получить текущее состояние камеры, то есть текущие настройки и т.д. Эти данные можно получить если сделать запрос: http://10.5.5.9/camera/sx?t=PASSWORD

PASSWORD - это WiFi пароль от камеры

В ответ камера передает данные. В библиотеке эти данные хранятся в строковой переменной firstLine, в функции listen(), в файле GoProControl.cpp

Вот так выглядят данные (я перевел в Hex, а то как строка не читается): 

00 00 00 00 00 0A 00 02 06 C4 00 FF 00 00 00 00 00 02 90 04 00 10 07 00 00 00 65 00 04 00 06 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 04 00 0A 00 00

Вот пример расшифровки:

00 
00 Current mode: 0 = VIDEO, 1 = PHOTO, 2 = BURST, 3 = TIMELAPSE
00 
00 
00 SPOTMETER: 0 = OFF, 1 = ON
0A BURST TIMELAPSE: 0 = 0.5 SEC, 1 = 1 SEC, 2 = 2 SEC, 5 = 5 SEC, 10 = 10 SEC, 40 = 30 SEC, 60 = 60 SEC
00 (bit 0) ISO: 0 = 6400, 1 = 1600, 2 = 400 / (bit 2) SHARPNESS: 0 = HIGH , 1 = MEDIUM, 2 = LOW
02 FOV: 0 = WIDE, 1 = MEDIUM, 2 = NARROW
06 PHOTORES: 0 = 11_MP_WIDE, 1 = 8_MP_MED, 2 = 5_MP_WIDE, 3 = 5_MP_MED, 4 = 7_MP_WIDE, 5 = 12_MP_WIDE, 6 = 7_MP_MED
00 
00 
FF 
00 
00 Video progress (hi byte)
00 Video progress (lo byte)
00 
00 VOLUME: 0 = OFF, 1 = 70%, 2 = 100%
02 LED: 0 = OFF, 1 = LED2, 2 = LED4
91 
02 
00 (bit 2) ORIENTATION: 0 = up, 1 = down, (bit 5) VIDEOREGION: 0 = NTSC, 1 = PAL
0D Photo remaining (hi byte)
87 Photo remaining (lo byte)
00 Photo count (hi byte)
00 Photo count (lo byte)
00 Video remaining (hi byte)
42 осталось времени видео
00 
12 количество видео
00 Recording
46 (bit 1) PROTUNE: 0 = OFF, 1 = ON / (bit 6): AUTO LOW LIGHT: 0 = OFF, 1 = ON / (bit 7) COLOR: 0 = COLOR, 1 = FLAT
00 
04 BURSTRATE: 0 = 3_1_SEC, 1 = 5_1_SEC, 2 = 10_1_SEC, 3 = 10_2_SEC, 4 = 30_1_SEC, 5 = 30_2_SEC, 6 = 30_3_SEC
00 PHOTO CONTINUOUS RATE: 0 = SINGLE, 3 = 3 FPS, 5 = 5 FPS, 10 = 10 FPS
04 WHITEBALANCE: 0 = AUTO, 1 = 3000K, 2 = 5500K, 3 = 6500K, 4 = CAM RAW
00 
00 
00
00 
00
00 
00
00 
00 
00 
00
03 Video resolution: 0 = WVGA, 1 = 720, 2 = 960, 3 = 1080, 4 = 1440, 5 = 2.7K, 6 = 4K, 7 = 2.7K (SUPERVIEW), 8 = 4K (SUPERVIEW), 9 = 1080 (SUPERVIEW), 10 = 720 (SUPERVIEW)
07 FPS: 0 = 12, 1 = 15, 2 = 24, 3 = 25, 4 = 30, 5 = 48, 6 = 50, 7 = 60, 8 = 100,  9 = 120, 10 = 240,
00 EXPOSURE: 6 = 2.0, 7 = 1.5, 8 = 1.0, 9 = 0.5, 10 = 0, 11 = +0.5, 12 = +1.0, 13 = +1.5, 14 = +2.0
0A Battery
00 
00

Расшифровку брал здесь: https://github.com/KonradIT/goprowifihack/blob/master/HERO3/CameraStatus.md

В общем, в конечном счете не проблема получить какие-то данные. Для меня сложность в другом. Я не знаю как вытянуть конкретные данные с переменной firstLine. Просто не умею работать со строками. Можете помочь? То есть можете продсказать, как со стороковой переменной вытянуть, на пример, текущий режим работы (Current mode: 0 = VIDEO, 1 = PHOTO, 2 = BURST, 3 = TIMELAPSE). Это, вроде как, второй символ... В общем для меня это путаница...

Перевести символ в bin и прочитать потом байты, это я смогу. Помогите разобрать firstLine.

mixail844
Offline
Зарегистрирован: 30.04.2012

судя по https://github.com/KonradIT/goprowifihack/blob/master/HERO3/CameraStatus.md

и по

Цитата:

Вот так выглядят данные (я перевел в Hex, а то как строка не читается): 

1 00 00 00 00 00 0A 00 02 06 C4 00 FF 00 00 00 00 00 02 90 04 00 10 07 00 00 00 65 00 04 00 06 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 04 00 0A 00 00

камера возвращает вам массив данных (в виде ASCII  или в виде массива байт - не ясно,так как не ясно что вы имеете ввиду под "я перевел в HEX) ,где значение по индексу в массиве означает состояние соотвествующего параметра камеры .

например. 

для индекса 1 (параметр Current Mode) данное,который в принятом массиве равен 0 , соотвстствуе состояние "Photo" 

для индекса 5 (параметр Burst TimeLapse), данные кооторые в принятом массиве  0х0А,соответствует 10 SEC.

то есть вам нужно написать программу на стороне ардуино,которая будет своего рода словарем ,то есть "пробегаться" по (нужным вам) индексам массива ,считывать с него данные,сопостовлять с табличкой  https://github.com/KonradIT/goprowifihack/blob/master/HERO3/CameraStatus.md и печатать в читаемом формате. 

forfrends
Offline
Зарегистрирован: 24.02.2015

Неправильно объясняю так как не знаю терминов. Управление делаю на ESP8266 (код пишу в Ардуино IDE). Управление работает без проблем.

Я с компьютера подключился к камере, сделал запрос: http://10.5.5.9/camera/sx?t=PASSWORD

В ответ получил файл: https://drive.google.com/open?id=1Lf3QmUUibG06igFnMqPpZDTpB_XKgsAN

его содержимое нормально можно просмотреть есль отрыть hex-редактором. 

00 00 00 00 00 0A 00 02 06 C4 00 FF 00 00 00 00 00 02 90 04 00 10 07 00 00 00 65 00 04 00 06 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 04 00 0A 00 00 - это то, что показывает hex-редактор

Если можно, помогите примером кода, как можно из переменно firstLine прочитать, на пример, 06 (установленное разрешение).

forfrends
Offline
Зарегистрирован: 24.02.2015

Все, разобрался. В самой библиотеке добавил еще одну функцию:

String GoProControl::getState(void){
  	String requestURL;
	uint64_t startTime = millis();
	String response;
	
	if (_camera == 1){			//HERO
		//old not in the todo list
	} else if (_camera == 2) {	//HERO2
		//old not in the todo list
	} else if (_camera == 3 || _camera == 31 || _camera == 32 || _camera == 33) {	//HERO3, HERO3+, HERO3BLACK, HERO3BLACK+
		
		requestURL = "http://10.5.5.9/camera/sx?t=igor1silenok";
		client.stop();
		if (!client.connect(_host.c_str(), _port)) {
			if (debugStatus){
				Serial.println("Connection lost");
				GoProConnected = false;
			}
		}
		client.print("GET " + requestURL + " HTTP/1.1\r\n");
		client.print("Connection: close\r\n\r\n");

		while (millis() - startTime < 3000) { //listen for 3 seconds
			while (client.available()) {
				char c = client.read();
				response += c;
			}
		}
		response.remove(0, (response.length()-56));
	} else if (_camera == 4) {	//HERO4
		//todo
	} else if (_camera == 5) {	//HERO5
		//todo
	} else if (_camera == 6) {	//HERO6
		//todo
	} else if (_camera == 7) {	//next?
		//future
	}	
  	return response;
}

Функция возвращает ответ от камеры. А дальше, конкретный байт можно узнать командой string.charAt(n)