智能小车4:串口通信

为什么串字是这么写,可能它是个象形字。



在arduino中,串口与这个意思比较相近,他只需要一条线。比如下图我就是从一个板子的串口发送到另一个板子,只用一根线,把它两给串起来,数据就通过这条线传输。



串口通信涉及到硬件与软件。串口硬件的发送和接收表示序列位的电脉冲数据。每个字节信息由各种组合的"0"和"1"构成。arduino所用的方案是0v表示比特值0,而5v(或3.3v)来表示比特值1.
我们在电脑上要发送数据到arduino也是通过串口,一处是串口监视器,一处是代码里的Serial.print.当然其它软件也可以能通过串协议发。比如SecureCRT.exe ,如下图。



 另外串口还可输出到processing,如下图:



串口打印(Serail.print)信息不能拼接字符串或变量,这是个很大的缺陷,可以用springf来实现,如:
 char co[100]="";
  int n=10;
 sprintf(co,"ddfdf%d",n);   

最后说一下串口通信协议,上面的代码串口的通信只是一个简单的Serail.print,这显然是有问题的。因为串口通信协议本来也有一些字符,如果发送的内容与协议内容有重合,就会出问题了。
硬件或软件串口库处理信息的发送和接收,信息里通常包括需要一起发送的数据。为了正确的解释信息,在接收侧需要识别每个消息的开始与结束。如果发送方与接收方都知道信息是如何组织的,
有意义的串口通信或任何类型的机器对机器的通信才能实现。这个消息里的信息正规的组织方式和对请求作出适当反应的规定就是通信协议。
 

消息可以包含标识消息的开始的一个或多个特殊字符,称为报头。一个或多个字符也可用于识别消息的结尾,称为报尾。比如最常用的tcp/ip协议,关于这个协议的分析可查看我的另一文章《Tcp协议数据结构完全解析》http://www.highersoft.net/html/notice/notice_269.html

如果想不通过arduino的代码,直接通过usb向arduino串口发送消息,怎么做呢?

如果实现了这个技术,想像空间太大了,家用电脑可直联单片机,发送和接收命令。下面我用python加一个usb转ttl的硬件设备来实现。

硬件是基础,这就是ch340,一头是usb, 一头有5根线,分别是5V,3.3V,GND,RX,TX 是不是都认识?很简单,这个与arduino的地rx,tx反接就可实现通信,当然5v,与GND也接一下。

下面就是python代码。环境准备先要安装python与PyCharm。安装好后,在pycharm里安装serial模块,代码十分简单:

import serial  # 导入模块
import sys
 
try:
    # 端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
    portx = "COM3"
    # 波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
    bps = 9600
    # 超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
    timex = 5
    # 打开串口,并得到串口对象
    ser = serial.Serial(portx, bps, timeout=timex)
 
    # 写数据,发送的命令为调本程序的第1个参数
    cmd = sys.argv[1]
    print(cmd)
    result = ser.write(cmd.encode("ISO-8859-1"))
    print("写总字节数:", result)
 
    ser.close()  # 关闭串口
 
except Exception as e:
    print("---异常---:", e)
这样就能发给arduino了。可以写个例子,arduino收到串口命令'o'就打开13号针的灯,收到'c'就关闭。

void setup() {
    Serial.begin(9600);
    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);

}

int incomingByte = 0;   // for incoming serial data
void loop() {
   if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();

           
            
            if(char(incomingByte)=='o'){
              digitalWrite(13,HIGH);
            }else if(char(incomingByte)=='c'){
             digitalWrite(13,LOW);
            }
    }
}
试验一下,哈哈,更广阔的应用等着我们。

文/程忠 浏览次数:0次   2017-08-10 14:03:42

相关阅读


评论: