简体   繁体   English

使用 ToF 距离传感器从处理上的 USB 端口传输数据

[英]Streaming data with a ToF distance sensor from an USB port on Processing

I'm trying to get the distance of the sensor on Processing but when I output the calue in the console I'm only able to see ASCII text.我试图在处理中获取传感器的距离,但是当我 output 控制台中的值时,我只能看到 ASCII 文本。 How shoudl I proceed here?我应该如何在这里进行?

import com.hamoid.*;

// Example by Tom Igoe

import processing.serial.*;

float angle = 0;
int myString;


Serial myPort;  // The serial port


void setup() {

  size(500, 500);
  // List all the available serial ports
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[3], 115200);

}

void draw() {
  background(0);
  // Expand array size to the number of bytes you expect
  byte[] inBuffer = new byte[4];



  while (myPort.available() > 0) {
    inBuffer = myPort.readBytes();
    myPort.readBytes(inBuffer);
    if (inBuffer != null) {
      String myString = new String(inBuffer);
      println(myString);


    }
  }

}

this is what I see when I run the code:这是我在运行代码时看到的:

T�T� T�T� T�T� T� T�T� T�T� T�T� T�T� T�T� T�T� T� T�T� T�T� T� T�T� T�T� T�T� T� T�T� T�T� T� T�T� T.T. T.T. T.T. T. T.T. T.T. T.T. T.T. T.T. T.T. T. T. T. T. T. T. T.T. T.T. T.T. T. T.T. T.T. T. T.T.

Let's try the obvious stuff and work our way from there.让我们尝试显而易见的东西并从那里开始工作。

You have 4 bytes, which means 32 bits.你有 4 个字节,这意味着 32 位。 That's awfully close to a 32 bits integer, especially other things hints at an integer.这非常接近 32 位 integer,尤其是 integer 的其他内容。 The only bad new here is that we don't know if it's really an integer, and even if it is, we still don't know if it's a signed integer or a unsigned integer.这里唯一的坏消息是我们不知道它是否真的是 integer,即使是,我们仍然不知道它是签名的 integer 还是未签名的 Z157DB7DF530023575EZ85D367。

First thing to try: we're using java, and java considers byte as a signed type.首先要尝试:我们使用的是 java,而 java 将字节视为有符号类型。 Let's cast it to an integer right off the bat:让我们立即将其转换为 integer:

// #1
if (inBuffer != null) {
  int distance = inBuffer;
  println(distance);
}

Alternatively, we may have some success with one of Byte's methods (it's basically the same operation, but we never know):或者,我们可能会使用 Byte 的一种方法取得一些成功(它基本上是相同的操作,但我们永远不知道):

// #2
if (inBuffer != null) {
  int distance = inBuffer.intValue();
  println(distance);
}

Maybe it's unsigned, now.也许它现在没有签名。 The difference lies in the fact the the sign (plus or minus, as in "this number is less or more than zero) takes bits, while with an unsigned number all the bits can be used to stock part of the number rather than the sign. You would have to cast it to "ignore" the sign, like this:区别在于符号(加号或减号,如“这个数字小于或大于零)占用位,而对于无符号数,所有位都可以用于存储部分数字而不是符号. 您必须将其强制转换为“忽略”标志,如下所示:

// #3
if (inBuffer != null) {
  int distance = (inBuffer & 0xFF);
  println(distance);
}

Start with #1 and then #3.从#1 开始,然后是#3。 I'm betting on #3, since there's no need for negative distance on a sensor.我打赌#3,因为传感器上不需要负距离。 Let me know what you find!让我知道你发现了什么!

========================================================== ==================================================== ========

Here's a primer on binary numbers.这是二进制数的入门。 (spoilers alert: binary is awesome) (剧透警告:二进制很棒)

As you probably know, a binary number is composed of 1 and 0. Nothing else.您可能知道,二进制数由 1 和 0 组成。没有别的。 And, as you may or may not know, that's the kind of stuff which our whole society is based upon.而且,你可能知道也可能不知道,这就是我们整个社会所依赖的那种东西。 This, and operators.这和运营商。 But let's stick to binary.但让我们坚持二进制。

When reading binary, you have to read from right to left.读取二进制时,必须从右向左读取。 I mean, if you're a cyborg or something you can probably just translate it more easily, just like we know that 5 000 000 is five million by reading it normally.我的意思是,如果您是机器人或其他人,您可能可以更轻松地翻译它,就像我们通过正常阅读知道 5 000 000 是 500 万一样。 But to really know how much the "5" is worth in "5 000 000", you have to start reading from the right, or else you don't know how many zero follows it - then it could mean anything.但是要真正知道“5”在“5 000 000”中的价值,你必须从右边开始阅读,否则你不知道它后面有多少个零——那么它可能意味着什么。

That's the same with binary, except that with decimal each number on the left is worth 10x more than the last, while in binary it's 2x.二进制也是一样,除了十进制,左边的每个数字都比最后一个值高 10 倍,而二进制是 2 倍。

In binary, first number on the right is worth 1. Every other number is worth twice the previous one.在二进制中,右边的第一个数字值 1。每隔一个数字的值是前一个数字的两倍。 So, for one byte, the values of the "ones" are as follow:因此,对于一个字节,“一”的值如下:

128 64 32 16 8 4 2 1
 1   1  1  1 1 1 1 1 == 255
 1   0  0  0 0 0 1 0 == 130
 0   0  0  0 1 1 0 1 == 13

That's a simple addition (just like any number when you think about it).这是一个简单的加法(就像您考虑的任何数字一样)。 It looks complicated, but it's easy once you get the idea.它看起来很复杂,但是一旦你明白了它就很容易了。

A byte is always 8 bits.一个字节总是 8 位。 Like these examples:像这些例子:

[00000000] == 0
[11111111] == 255
[00001101] == 13

Now, if we look at the specs for your sensor, we find these 3 informations:现在,如果我们查看您的传感器的规格,我们会发现以下 3 个信息:

8 data bits
no parity bit
one stop bit

Which means the following:这意味着以下内容:

  1. The data will be contained in bunches of 8 bits (one byte).数据将包含在 8 位(一个字节)的串中。
  2. There is no bit reserved for error detection没有为错误检测保留位
  3. One special bit will tell when communication starts or ends.一个特殊的位将告诉通信何时开始或结束。

We still don't know if the data will be signed or unsigned (spoiler alert again: probably unsigned), but we already start seeing patterns here.我们仍然不知道数据是签名还是未签名(再次剧透警告:可能未签名),但我们已经开始在这里看到模式。 Even in the strings you obtained, we can detect a clear pattern:即使在您获得的字符串中,我们也可以检测到清晰的模式:

84 6 177 84 6 194 177 84 6 189 203 84 6 194 177 84 6 84 6 177 84 6 194 177 84 6 189 203 84 6 194 177 84 6

Problem is, these are probably not integers.问题是,这些可能不是整数。 They are binary interpreted as integer by the machine.它们被机器二进制解释为 integer That's not the same.那不一样。

Your sensor is "free running", which means that it's never waiting for you.您的传感器是“自由运行”的,这意味着它永远不会等待您。 It's always sending signals.它总是在发送信号。 Every time it's finished sending a number, it starts sending another one, all the time.每次发送完一个号码,它就会开始发送另一个号码,一直如此。 This could explain why you get this kind of loop in your data.这可以解释为什么您的数据中会出现这种循环。

Now, if we go into more details, we can see that your sensor's protocol isn't exactly just "sending distances".现在,如果我们更详细地了解 go,我们可以看到您的传感器协议不仅仅是“发送距离”。 It's more complex than that.它比这更复杂。 Here's how it works:以下是它的工作原理:

  1. It starts with one byte containing a 7 bits address and a 0 (the "write bit").它以一个包含 7 位地址和 0(“写入位”)的字节开始。 That's probably what you read as "6".这可能就是你读到的“6”。
  2. It sends another bit with the address, but with a "1" at the end (the "read" bit"). That's probably what you read as "84".它发送另一个带有地址的位,但末尾有一个“1”(“读取”位“)。这可能就是你读为“84”的内容。
  3. It sends 2 bytes of data containing a 16 bits number, which is your measurement in mm.它发送包含 16 位数字的 2 个字节的数据,这是您的测量单位,以毫米为单位。
  4. It sends a checksum (one byte).它发送一个校验和(一个字节)。

That would make sense.这是有道理的。 After all, your sensor is supposed to be read in millimeters, and could reach up to 60 000 mm, which is not possible in only one byte (which tops at 255, remember?).毕竟,您的传感器应该以毫米为单位读取,并且可以达到 60 000 毫米,这在仅一个字节中是不可能的(最高为 255,记得吗?)。 In fact, you can't write 60 000 in binary with less than 16 bits.事实上,你不能用少于 16 位的二进制写 60 000。

Now, how do we interpret these?现在,我们如何解释这些?

First thing, port.read() reads only one byte at a time, so it cannot read 16 bits in one go.首先, port.read()一次只读取一个字节,因此它无法读取 go 中的 16 位。 That's one of the reasons the numbers you get makes no sense (8 bits only range from 0 to 255, so you cannot get a higher value either).这就是您得到的数字没有意义的原因之一(8 位的范围仅从 0 到 255,因此您也无法获得更高的值)。

Instead of trying to get a number right away, let's see if we can calculate the real values behind your current inputs by throwing them back into binary:与其试图立即得到一个数字,不如让我们看看我们是否可以通过将它们扔回二进制来计算当前输入背后的真实值:

194 == [11000010]
177 == [10110001]
[11000010 10110001] == 49 841


189 == [10111101]
203 == [11001011]
[10111101 11001011] == 48 587

Were you pointing it at something about 5 meters away?你把它指向大约 5 米外的东西吗? Would that make sense??这有意义吗?? Try pointing the sensor toward something which you know the approximative distance and let's do this again, just for fun!尝试将传感器指向您知道近似距离的东西,让我们再做一次,只是为了好玩! And science!还有科学!

@laancelot I've used this sketch and I'm getting integers now, but not the right ones. @laancelot我已经使用了这个草图,现在我得到了整数,但不是正确的。 Eg below:例如下面:

84 6 177 84 6 194 177 84 6 189 203 84 6 194 177 84 6 84 6 177 84 6 194 177 84 6 189 203 84 6 194 177 84 6

This is the sketch I'm using on processing:这是我在处理时使用的草图:

    import com.hamoid.*;

// Example by Tom Igoe

import processing.serial.*;

int distance;

Serial port;  // The serial port

void setup() {

  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  port = new Serial(this, Serial.list()[3], 115200);

}

void draw() {
  if (0 < port.available()) {  // If data is available to read,
    distance = port.read(); 
  }
    println(distance);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM