Всем привет. Хочу написать интерфейс для управления для Ардуино, есть 2 варианта: Qt или PHP. Могу передать одно значение для одной переменной, но двум не получается. Как быть? Например: хочу передать 25 и 50 двум переменным, которые будут использоваться в условиях....
А что именно не получается? Послать? Прочитать? Чтение в Арудине: Код (Text): void loop() { if (Serial.available() >= 2) { a1 = Serial.read(); // первая переменная a2 = Serial.read(); // вторая переменная } } еще можно сразу прочесть в массив: Код (Text): uint8_t a[2]; ... Serial.readBytes((char *)a, 2); // в a[0] первая переменная, а в a[1] вторая
Не очень понято Я как понял он хочет на компе данный с ардуины зачитать, ибо в дуню ни куТе ни пхп не запихнуть
обе переменные кажись будут хранить последнее значение передаваемое на порт, нет? А мне нужно что бы, две переменные могли сохранить совершенно разные цифры. По Вашему совету пробовал, не получилось. (
В приведенном примере читается два значения размером 1 байт. Соответственно ожидается, что в буфере последовательного порта на ардуине появится два байта, которые последовательно, один за другим, считываются в две переменные. Соответственно на передающей стороне должны быть переданы тоже один за другим два байта - два однобайтовых значения переменных. Возможно, проблема в том, что передаваемые значения получаются размером больше байта, то это надо учесть и использовать для приема и передачи сущности одинакового размера. Для приема двух двухбайтовых переменных придется сделать что-то вроде int a[2]; ... Serial.readBytes((char *)a, 4); // в a[0] первая переменная, а в a[1] вторая Т.е. читается четыре байта - по два байта на переменную. И передавать, соответственно, двухбайтовые значения четырехбайтовым пакетом. Другая проблема, которая может возникнуть - синхронизация передачи и приема данных. Может получиться, что в первую переменную будет попадать значение для второй, а во вторую для первой. Или случится переполнение буфера, поскольку ардуина не будет успевать забирать данные по какой-то причине. Чтобы этого избежать надо обрамлять передачу какими-то характерными посылками. Потом ожидать в потоке признак начала, читая байт за байтом, и только потом читать значения переменных.
Вы не сталкивались с такими проблемами? Последний абзац как можно реализовать? Я понятия не имею пока) До этого передавал два значения и как Вы описывали две переменные моментами принимали не свои значения (
Я передавал по последовательному порту большое количество разных данных. Вроде все передавалось нормально. Оформлял как передачу буфера, скармливая в качестве буфера при приеме и передаче структуру с данными. Примерно так. Со стороны ардуины: Код (Text): void loop() { struct t_data2 { uint8_t header; uint8_t a1; uint8_t a2; uint8_t checksumm; } data2; if (Serial.available()) { int rc=ReadData((char*) &data2, sizeof(struct t_data2)); if (rc==siztof(struct t_data2)) { a1 = data2->a1; // первая переменная a2 = data2->a2; // вторая переменная } } }nt ReadData(char *buf, byte bufsize) { byte i=0; unsigned long startmillis=millis(); //первый байт while ((millis()-startmillis<100)&&(i<bufsize)) // отрабатываем вариант с нулевой длиной буфера и таймаут (100 мс) { if (Serial.available()) { buf[0]=Serial.read(); if (buf[0]==0xFF) // проверяем первый байт - индикатор начала передачи, должен быть 0xff { i++; break; } } } if (i<1) return(0); // если так и не дождались символа начала передачи - выход // чтение оставшихся байт while ((millis()-startmillis<100)&&(i<bufsize)) { if (Serial.available()) { buf[i]=Serial.read(); i++; } } if (i<bufsize) retun(-1); // считали не все, значит посылка была с ошибкой // проверяем что-то вроде контрольной суммы. int crc=0; for ( int j=0; j<i-1; j++ ) crc+=buf[j]; if (buf[i-1]!=crc) retun(-1); // сумма не совпала, значит посылка была с ошибкой return(i); } Соответственно, с другой стороны нужно заполнить и записать в порт такую же структуру с таким же выравниванием. В первом поле признак начала передачи, дальше поля для значений переменных, в последнем поле сумма всех предшествующих полей структуры - что-то вроде контрольной суммы. Eсли я правильно понял, то по умолчанию для ардуины выравнивание структур идет на байт, если не прав, поправьте.
Код (Text): <?php $num = 0; $numb = 0; if(isset($_POST['port'])){ $num = (int)$_POST['port']; exec("mode com5: BAUD=9600 PARITY=n DATA=8 STOP=1 to=off dtr=off rts=off"); $fp = fopen('COM5:', 'wb'); if($fp){ sleep(0.2); $_port = sprintf('%d',$num); fwrite($fp,$_port); echo 'SEND: '.$_port; sleep(0.2); fclose($fp); } } ?> <form action="" method="POST"> <input type="text" name="port" value="<?php echo htmlspecialchars($num); ?>" /> <input type="submit" /> </form> Вот код, с помощью которого я отправляю значения. Вопрос, можно но ли передать не символ, а символы, то есть я передаю с веб хоста 456, а ардуино это читает как 4, 5 и 6 отдельно. Как это можно решить?
Если я правильно понял, то число просто передается строкой. Чтобы его принять, надо всего лишь прочитать строку. Лучше ее ограничить символами начала и конца, чтобы на принимающей стороне обрабатывались только корректные посылки, например " 456\n" (т.е. пробел - признак начала, перевод строки - признак завершения). Для считывания ардуиной можно воспользоваться методом readBytesUntil класса Serial, в котором задается символ окончания строки. Можно самостоятельно считывать символ за символом, ожидая символ начала, затем помещать в буфер символы посылки, пока не встретится символ завершения. А потом остается только конвертировать содержимое буфера в число, например, примерно так, res=0; for (int i=0;i<len;i++) res=(res*10)+(s-0x30);