Доброго времени суток! Разбирая примеры с официального сайта Процессинга, потратил почти два дня, на казалось бы простой пример. Нажимаем кнопку на Ардуинке у нас на мониторе ПК меняет цвет квадратик. Ни что не предвещало подвоха: Код для Ардуино, пришлось подправить под себя, у меня кнопка на 8 пине, да и ардуино IDE ругалось на BYTE: Код: // Code for sensing a switch status and writing the value to the serial port int switchPin = 8; // Switch connected to pin 8 void setup() { pinMode(switchPin, INPUT); // Set pin 0 as an input Serial.begin(9600); // Start serial communication at 9600 bps } void loop() { if (digitalRead(switchPin) == HIGH) { // If switch is ON, Serial.print(1); // send 1 to Processing } else { // If the switch is not ON, Serial.print(0); // send 0 to Processing } delay(100); // Wait 100 milliseconds } Программа работает так, при нажатии кнопки Ардуина отправляет в СОМ порт "1", отпускаем - "0". Если не прав - замечания приветствуются!)) Код для Процессинга: Код: // Read data from the serial port and change the color of a rectangle // when a switch connected to the board is pressed and released import processing.serial.*; Serial port; // Create object from Serial class int val; // Data received from the serial port void setup() { size(200, 200); frameRate(10); // Open the port that the board is connected to and use the same speed (9600 bps) port = new Serial(this, "COM18", 9600); } void draw() { if (0 < port.available()) { // If data is available, val = port.read(); // read it and store it in val } background(255); // Set background to white if (val == 0) { // If the serial value is 0, fill(0); // set fill to black } else { // If the serial value is not 0, fill(204); // set fill to light gray } rect(50, 50, 100, 100); } Программа работает так, при нажатии и отпускании кнопки на экране ПК меняет цвет квадратик.))) Если не прав - замечания приветствуются!)) Танцы с бубном в течении дня меня привели к вот этому: я вставил распечатку переменной Код: println(val); и что получилось на выходе Лезем в ASCII - "48" - "0" а "49" - "1". Вопрос номер 1 - как такое получилось? Вопрос номер 2 (риторический) - как нерабочий пример могли выложить на офсайт. Изменение одной строки заставит все работать как задумано: Код: if (val == 48) Но мы легких путей не ищем, роем дальше и разбираем по косточкам пример от Валерия. Пришлось код для Процессинга изменить: Код: // Read data from the serial port and change the color of a rectangle // when a switch connected to the board is pressed and released import processing.serial.*; Serial port; // Create object from Serial class float val=1; // Data received from the serial port void setup() { size(200, 200); frameRate(30); // Open the port that the board is connected to and use the same speed (9600 bps) port = new Serial(this, "COM18", 9600); port.bufferUntil('\n');//считываем одно значение строки } void draw() { println(val); background(255); // Set background to white if (val == 0) { // If the serial value is 0, fill(0); // set fill to black } else { // If the serial value is not 0, fill(204); // set fill to light gray } rect(50, 50, 100, 100); } void serialEvent (Serial port) { val = float(port.readStringUntil('\n')); //считываем с порта значение и записываем в переменную input } Что за собой повлекло изменения кода для Ардуино, нужно было переводить после каждой отправки на новую строку - используем в Процессинге ('\n'). И отправку сделал только после изменения, что бы не нагружать порт. Выкладывать не буду, так как он конвертирован в FLProg, и знатоки на него ругаются))). Вопрос 3 - менял тип переменной val на int - код не работает, почему? Вопрос 4 - чем отличаются bufferUntil от buffer и readStringUntil от readString, в двух словах - с офсайта ничего не понял. Вопрос 5 - как обойтись без ('\n')? Пробовал делать так: Код: void serialEvent (Serial port) { val = float(port.readStringUntil(1)); //считываем с порта значение и записываем в переменную input } Не получается по одному символу выдергивать((( Всем бобра!
Код: if (digitalRead(switchPin) == HIGH && toggle==1) Serial.print(1); Toggle=0 elseif (digitalRead(switchPin) == LOW && toggle==0) Toggle=1 Serial.print(0); --- Сообщения объединены, 7 янв 2016 --- Я так понял что при нажатие кнопки у вас данные отправляются постоянно , поэтому и нужно закрывать передачу с помощью переменной toggle
Программу для отправки в UART делал на FLProg. Логика работы и настройка UARTа - отправка в уарт производиться только при изменении состояния кнопки заканчивая переводом строки. Вот код для Ардуины выданный FLProg: Код: bool _gtv1 = 0; //состояние кнопки bool _bounse1S = 0; bool _bounse1O = 0; unsigned long _bounse1P = 0UL; bool _stou1; bool _swi2; void setup() { Serial.begin(9600); pinMode(8, INPUT); } void loop() { bool _bounceTmp1 = (digitalRead (8)); if (_bounse1S) { if (millis() >= (_bounse1P + 40)) {_bounse1O= _bounceTmp1; _bounse1S=0;} } else { if (_bounceTmp1 != _bounse1O ) {_bounse1S=1; _bounse1P = millis();} } if(_gtv1) {_swi2=1;} else {_swi2=0;} _gtv1 = _bounse1O; if (1){if(!(( _swi2)==(_stou1))){Serial.println(_swi2);}} _stou1 = _swi2; }
Вырисовываются ответы заданные в теме: Метод print() используют в основном для печати на серийный монитор, так как она использует ASCI. Еще есть Serial.write(), который отправляет сигнал в виде байтов. Для того, чтобы все делалось как надо, лучше использовать SerialEvent() как во втором примере в вопросе. Для этого нужно со стороны Ардуино все отправлять в виде строки, а на выходе переводить строку в нужный тип данных. Информация на сайте довольно плохо обновляется, пример был актуальным до появления новой версии серийной библиотеки. buffer() - позволяет указать точное число байтов для чтения, bufferUntil() - ASCI символ на котором обрывается сообщение, можно использовать его и readString() одновременно, а можно вместо них использовать readStringUntil(), это типа два в одном. вместо "\n" можно использовать что угодно - любой символ, но и "\n" нормально, его просто нужно дописывать в конец каждого сообщения. Хотя это все для простого примера вкл/выкл не нужно, так как можно постоянно читать каждый входящий байт беспрерывно он или 1 или 0. А вот если нужно отправлять показания сенсоров, тогда SerialEvent(). Код для Процессинга (Тут Буфер не имеет смысла использовать, потому что нам нужно просто получать всю строку, которая отправляется не постоянно, а только когда меняется значение.): Код: import processing.serial.*; Serial myPort String inString; int val; void setup() { size (100, 100); myPort = new Serial(this, Serial.list()[0], 9600); } void draw() { background(0, 150, 120); if (val == 0) { fill(50, 50, 180); } else { fill(200, 120, 50); } ellipse(width/2, height/2, width, height); } void serialEvent(Serial p) { inString = p.readString(); val = int(inString); print(val); } Большое спасибо Ater за разъяснения темы.