Передача дробного числа в процессинг.
- Войдите на сайт для отправки комментариев
Втр, 30/04/2013 - 09:16
Подскажи как передать дробь?
Мысли пока такие, процессинг принимает только целые. В Ардуино я умножаю дробь на (пусть десятичная) 10, получаю целое значение и передаю его в процессинг, как в процессинге его пробразовать в дробь?
Может есть еще способы?
Спасибо!
Всё зависит от лени подумать. Можно передавать отдельно целую, и отдельно дробную части. Можно преобразовать число в строку и передать "как есть". А ваш вариант с умножением на 10 вообще непонятно почему вызывает вопросы, если в дуине умножили, в процессинге разделите обратно. Или есть проблемы с использованием функции float()?
Всё зависит от лени подумать. Можно передавать отдельно целую, и отдельно дробную части. Можно преобразовать число в строку и передать "как есть". А ваш вариант с умножением на 10 вообще непонятно почему вызывает вопросы, если в дуине умножили, в процессинге разделите обратно. Или есть проблемы с использованием функции float()?
Есть проблемы с float.
Вот по смотрите мой скетч процессинга. Это я взял с видеоурока. Но понимаю, что для моих целей с расчетами в дальнейшем это не пойдет. Как передать в Процессинг число именно как число с записью в float?
Спасибо!
//открываем порт Serial import processing.serial.*; Serial port; //Задаем переменные String t = ""; //температура String h = ""; //влажность String data = ""; //хранит строку целиком int index = 0; //задается строка где будет стоять запятая. PFont font; //задаем шрифт void setup() { size (300, 300); //задаем размер окна port = new Serial(this, "COM3", 9600); port.bufferUntil('.'); font = loadFont("BookmanOldStyle-Bold-96.vlw"); //задаем шрифт textFont (font, 64); } void draw() { background(255,255,255); //задаем фон fill(82, 171, 82); text("T=", 40, 100); text(t, 128, 100); //задаем пустую строку где будут содержаться данные температуры text("H=", 40, 200); text(h, 128, 200); //задаем пустую строку где будут содержаться данные влажности } void serialEvent (Serial port) { data = port.readStringUntil ('.'); data = data.substring(0, data.length() - 1); index = data.indexOf(","); t = data.substring(0, index); h = data.substring(index+1, data.length()); }Ваш скейтч изначально работает не с числами, а со строками, а значит вы и с дуины отправляете не число, а строку. Вы для начала определитесь что вам нужно - строки или числа.
Лучше так и оставить, строками, потому что "числами" не получится, ввиду разных размеров (возможно, представления и прочих нюансов) float на Ардуино и на компе.
Вообще, обмен бинарными, даже целыми числами сопряжен с множеством проблем (размер, big-endian/little-endian и т.п.)
Для функции serialEvent нет комментариев, разберитеть для чего нужна каждая строка в отдельности, это должно снять вопросы о том, как передать данные в другом формате. А с точки зрения понимания процесса возможно лучше вообще отказаться от данной функции в пользу структуры
while (Port.available() > 0) { }Serial port; PFont font; int T1, T2, T3, T4, H1, H2, H3, H4, R, G, B; float t, h; void setup() { size (400, 400); //задаем размер окна port = new Serial(this, "COM3", 9600); port.bufferUntil('.'); font = loadFont("Andalus-100.vlw"); //задаем шрифт textFont (font, 100); } void draw() { while (port.available() > 0) { T1 = port.read(); delay(10); T2 = port.read(); delay(10); T3 = port.read(); delay(10); T4 = port.read(); delay(10); H1 = port.read(); delay(10); H2 = port.read(); delay(10); H3 = port.read(); delay(10); H4 = port.read(); } background(255, 255, 255); fill(46, 209, 2); text("T=", 15, 150); text(T1-48, 120, 150); text(T2-48, 180, 150); text(".", 230, 150); text(T4-48, 245, 150); text("C", 305, 150); text("H=", 15, 300); text(H1-48, 120, 300); text(H2-48, 180, 300); text(".", 230, 300); text(H4-48, 245, 300); text("%", 305, 300); }delay() - это плохо, очень вероятны непредсказуемые глюки в чтении кома.
обычно данные по com-порту передаются в формате [заголовок строки] [данные].
String bufer=""; //буфер чтения import processing.serial.*; //открытие порта и другие начальные установки упущены void draw() { //***********************основной цикл while (myPort.available() > 0) { char inByte = myPort.readChar(); // прочитать символ с порта if (inByte==char(13)) { // после прочтения символа начала строки: char(13) - пример fi(); // отправить буфер на обработку bufer=""; } // сбросить буфер else {bufer=bufer+inByte;} // сбор данных в буфер до обнаружения нового заголовка } } //***********************************draw void f1 () { if (bufer.length()==64) { //если буфер чтения правильной длины (64 - пример) // выполнить обработку буфера (разделить на подстроки и преобразовать в нужный формат) } }корявенько написал, но как то так лучше
Код на с++ для ардуино, преобразующий float (или массив float)
в последовательность символов постоянной длины.
void serialPrintFloatArr(float * arr, int length) { for(int i=0; i<length; i++) { serialFloatPrint(arr[i]); Serial.print(","); } } void serialFloatPrint(float f) { byte * b = (byte *) &f; for(int i=0; i<4; i++) { byte b1 = (b[i] >> 4) & 0x0f; byte b2 = (b[i] & 0x0f); char c1 = (b1 < 10) ? ('0' + b1) : 'A' + b1 - 10; char c2 = (b2 < 10) ? ('0' + b2) : 'A' + b2 - 10; Serial.print(c1); Serial.print(c2); } } void writeArr(void * varr, uint8_t arr_length, uint8_t type_bytes) { byte * arr = (byte*) varr; for(uint8_t i=0; i<arr_length; i++) { writeVar(&arr[i * type_bytes], type_bytes); } } // thanks to Francesco Ferrara and the Simplo project for the following code! void writeVar(void * val, uint8_t type_bytes) { byte * addr=(byte *)(val); for(uint8_t i=0; i<type_bytes; i++) { //Serial1.write(addr[i]); Serial.write(addr[i]); } }В процессинге распарсиваем эту строку обратно во float
float decodeFloat(String inString) { byte [] inData = new byte[4]; if(inString.length() == 8) { inData[0] = (byte) unhex(inString.substring(0, 2)); inData[1] = (byte) unhex(inString.substring(2, 4)); inData[2] = (byte) unhex(inString.substring(4, 6)); inData[3] = (byte) unhex(inString.substring(6, 8)); } int intbits = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff); return Float.intBitsToFloat(intbits); }Работает отлично.
Придумно не мной, это часть библиотеки http://www.varesano.net/projects/hardware/FreeIMU#v0.4