1. В сообществе нашего форума Вконтакте создан раздел по продаже электронных компонентов.
    Каждый может продать в нем свои залежавшиеся детали. Подробности здесь.

Нолики, единички, "Аски код", вопрос к знатокам!

Тема в разделе "Processing", создана пользователем monitorrr, 7 янв 2016.

  1. monitorrr

    monitorrr В доску свой

    Сообщения:
    331
    Симпатии:
    94
    Род занятий:
    инженер сервиса
    Адрес:
    Алматы
    Доброго времени суток!
    Разбирая примеры с официального сайта Процессинга, потратил почти два дня, на казалось бы простой пример.
    333333333333.jpg
    Нажимаем кнопку на Ардуинке у нас на мониторе ПК меняет цвет квадратик. Ни что не предвещало подвоха:
    Код для Ардуино, пришлось подправить под себя, у меня кнопка на 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);
    и что получилось на выходе
    1111111111111.jpg
    Лезем в 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
    
    
    }
    Не получается по одному символу выдергивать(((
    Всем бобра!
     
    : processing, arduino, serial, com
  2. Дмитрий BASIC

    Дмитрий BASIC В доску свой

    Сообщения:
    203
    Симпатии:
    107
    Код:
    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
    Последнее редактирование: 7 янв 2016
  3. monitorrr

    monitorrr В доску свой

    Сообщения:
    331
    Симпатии:
    94
    Род занятий:
    инженер сервиса
    Адрес:
    Алматы
    Программу для отправки в UART делал на FLProg.
    Логика работы и настройка UARTа - отправка в уарт производиться только при изменении состояния кнопки заканчивая переводом строки.
    11111.jpg
    Вот код для Ардуины выданный 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;
    
    
    
    
    }
  4. monitorrr

    monitorrr В доску свой

    Сообщения:
    331
    Симпатии:
    94
    Род занятий:
    инженер сервиса
    Адрес:
    Алматы
    Вырисовываются ответы заданные в теме:
    Метод 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 за разъяснения темы.

Поделиться этой страницей