Arduino和processing实现串口通信

2021-02-24 11:22:09 浏览数 (1)


Arduino和processing是一对好基友。。。

1.通过串口将Arduino的输出传递给Processing进行输出。

Arduino代码:

代码语言:javascript复制
int data=12345; 
void setup()
{
  Serial.begin(9600);//rate
}
void loop()
{
  Serial.println(data); //send data, end up with 'n'
  delay(1000);
}

Processing代码:

代码语言:javascript复制
import processing.serial.*;

String message;
String temp;
Serial myPort;

void setup(){
  myPort = new Serial(this,"COM3",9600); //Set Serial Port
}

void draw(){
  if(myPort.available()>0){
    temp = myPort.readString(); //temp for read bytes
    for(int i = 0; i < temp.length(); i  ){
      //if meet the end mark
      if(temp.charAt(i) == 'n'){
        println(message);
        message = "";  //clean string
      }
      else
        message  = temp.charAt(i);  //store byte
    }
  }
}

注意:

由于串口流通的数据都是bytes而没有字符串概念,所有发送数据都会按一个byte一个byte缓存,不论是否是连续字符串;而读取时会取走所有缓存bytes,不论它们是否是一个、半个还是多个字符串。

Arduino和Processing的数据收发速度是不一样的。如果用Arduino延时较长时间,Processing可能读取一个字符串或字符串的一部分。如果Arduino延时较短,Processing可能读取多个字符串,但不一定完整。在读取字符串的时候,无法确定上一个字符串是否被读取了,当前字符串是否缓存完毕,因为字符串都已经切成了bytes,连成一串。这个问题是串口通信本身造成的,一定会出现。

一种解决方法是,通过在接收端缓存数据来解决这个问题。为传输数据设置一个结束标记,如’n’(换行符),就能在接收到的数据流中识别到一个字符串的结尾。当未遇到结束标记,就一直将串口数据保存在一个buffer变量中,继续接收,当遇到结束标记,即完成缓存。

2.通过串口将rotation sensor的转动角度发送给Processing,并绘制出可视化的图形。

Arduino代码:

代码语言:javascript复制
int potPin = 0; // 电位器第二针脚接在模拟口0上

void setup() {
  // 启动串口,波特率为9600
  Serial.begin(9600);
}

void loop() {
  // 读取电位器电压
  int sensorValue = analogRead(potPin);
  
  // 因为processing的serial.read()只支持0-255之间的数值,所以需要把0-1023数值除以4,缩放到0-255之间
  Serial.write(sensorValue/4); 
  
  delay(100);
}

Processing代码:

代码语言:javascript复制
import processing.serial.*;

Serial serial;  
int sensorValue;

void setup() {
  // 设置画布大小为 305 x 200 
  size(305, 200);  //设置305的原因是arduino ADC口输入过来的数值是0-255,加上圆形半径50,刚好305.
  
  // 打开串口,设置波特率为9600
  serial = new Serial(this, "COM3", 9600);
}

void draw() {
  if ( serial.available() > 0) {
    // 读取从串口产过来的Sensor数值。
    sensorValue = serial.read() 25;  // 25的原因是后面设置圆形半径为50,为了让圆形起点与重点贴边,就需要 25半径。
    println(sensorValue);
    
    // 在画布内画一个
    background(255); // 背景为白色
    fill(255,0,0);   // 圆形内填充为红色
    ellipse(sensorValue, 100, 50, 50);
  }  
}

知识点补充:

ellipse:(圆形)

ellipse(x,y,width,height) x,y是圆形坐标点,指的是圆心。 width是圆的水平直径 height是圆的垂直直径 比如120,60这样画出来的就是一个椭圆了。

rect:(矩形) rect(x,y,width,height) x,y指的是矩形坐标点,是左上角那个点。 width是矩形宽度 height是矩形高度 默认模式是CORNER。 画矩形有三种模式: 1、CORNER:rect(左上x,左上y,宽,高) 2、CENTER:rect(中心x,中心y,宽,高) 3、CORNERS:rect(左上x,左上y,右下x,右下y)

例子: rectMode(CENTER); rect(150,150,200,200)

PS:貌似还是把代码当作Java显示高亮效果更好。

0 人点赞