【问题标题】:Can't send data to my Arduino Uno using Cocoa (IOKit)无法使用 Cocoa (IOKit) 向我的 Arduino Uno 发送数据
【发布时间】:2013-04-09 13:49:44
【问题描述】:

我目前正在尝试通过 Mac 应用程序将数据发送到我的 Arduino。我的Arduino Uno 中的代码如下所示:

void setup()
{
    pinMode (2, OUTPUT);
    pinMode (3, OUTPUT);
    pinMode (4, OUTPUT);

    Serial.begin (9600);
}

void loop ()
{
    digitalWrite (2, HIGH);

    if (Serial.available () > 0)
    {
        int c = Serial.read();

        if (c == 255)
        {
            digitalWrite (3, HIGH);
        }
        else
            digitalWrite (4, HIGH);
    }
}

这是我在 XCode 项目中的代码:

// Open the serial like POSIX C
serialFileDescriptor = open(
                            "/dev/tty.usbmodemfa131",
                            O_RDWR |
                            O_NOCTTY |
                            O_NONBLOCK );

struct termios options;

// Block non-root users from using this port
ioctl(serialFileDescriptor, TIOCEXCL);

// Clear the O_NONBLOCK flag, so that read() will
//   block and wait for data.
fcntl(serialFileDescriptor, F_SETFL, 0);

// Grab the options for the serial port
tcgetattr(serialFileDescriptor, &options);

// Setting raw-mode allows the use of tcsetattr() and ioctl()
cfmakeraw(&options);

speed_t baudRate = 9600;

// Specify any arbitrary baud rate
ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate);

NSLog (@"before");
sleep (5); // Wait for the Arduino to restart
NSLog (@"after");

int val = 255;
write(serialFileDescriptor, val, 1);
NSLog (@"after2");

因此,当我运行应用程序时,它会等待五秒钟,但随后会冻结。控制台的输出是这样的:

before
after

那么,我在这里做错了什么?

更新:所以,当我注释掉这一行时

fcntl(serialFileDescriptor, F_SETFL, 0);

程序没有冻结,但我的 Arduino 仍然没有得到任何数据。

【问题讨论】:

  • 这不是 IOKit 代码吧?
  • 我使用这里提供的代码:playground.arduino.cc/Interfacing/Cocoa#IOKit
  • 这并不能直接回答你的问题(Josh Freeman 的回答就是这样做的),但你可以看看ORSSerialPort,这使得在 Objective-C/Cocoa 中使用串行端口变得非常容易。
  • ORSSerialPort 在编译我的应用程序时总是给我一个链接器错误 - 无法让它正常工作
  • Jan,请确保您链接的是 ORSSerialPort 所依赖的 IOKit.framework。为此,您可以将其添加到目标的“Link Binary with Libraries”构建阶段。见截图here

标签: objective-c cocoa serial-port arduino iokit


【解决方案1】:

1) write() 调用的第二个参数不正确 - write() 需要一个指向要写入的字节的指针。要将数值变量的值写入字节,请传递变量的地址,而不是变量本身:

write(serialFileDescriptor, (const void *) &val, 1);

关于 write() 的更多信息: https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/write.2.html

2) 对本地 termios 变量、选项的更改 - 例如对 cfmakeraw() 的调用 - 不会影响终端设置;为了使用更改后的选项更新终端设置,请调用 tcsetattr():

cfmakeraw(&options);

// ...other changes to options...

tcsetattr(serialFileDescriptor, TCSANOW, &options);

有关 Mac OS X 串行通信的更多信息: http://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/SerialDevices.html

【讨论】:

  • 您好,感谢您的回答。不幸的是,它仍然对我不起作用(程序仍然冻结{我猜它在等待答案或其他东西,因为它在写入时冻结}。这是我的新代码:pastebin.com/ax4tvLbg
【解决方案2】:

您的 Arduino 草图应该是 uint8_t,而不是 int,并且您对 write() 的 IOKit 调用也应该使用 uint8_t。

【讨论】:

  • 改了但还是不行。我在我的 arduino 上没有收到任何消息。
  • 嗯。从 Xcode 运行股票演示项目以及我的 Arduino 作品上的演示草图。是时候开始区分它们了。
猜你喜欢
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多