JP762
JP762

Reputation: 31

Issue with arduino/mac communication using ORSSerialPort

I am trying to send a three digit number from an XCode foundation command-line tool to an arduino over USB as a proof of concept for sending a data stream. The arduino code is supposed to flash a light the number of times that the number in the incoming data is. It works perfectly using the serial monitor in the arduino IDE, but when I try using the Objective-C program, which uses ORSSerialPort, the Rx light flashes on the arduino, indicating that it has received data, but nothing else happens.

Here is the Objective-C code:

#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import "ORSSerialPort.h"
#import "ORSSerialPortManager.h"



int main(int argc, const char * argv[])
{
    @autoreleasepool {

        ORSSerialPort *arduino = [ORSSerialPort serialPortWithPath:@"/dev/tty.usbmodem26231"];
        //initalizes ORSSerialPort instance

        NSString *string = @"012"; //creates string from the 3-digit number

        NSData *outgoingdata = [string dataUsingEncoding:NSASCIIStringEncoding]; 
        //encodes string using ASCII

        int number = 1200;
        NSNumber *baudrate = [[NSNumber alloc] initWithInt:number];
        //initializes an NSNumber for the baud rate

        [arduino open]; //opens port
        baudrate = arduino.baudRate; //sets baud rate
        [arduino sendData:outgoingdata]; //sends data
        [arduino close]; //closes port

        NSLog(@"%@ sent", string); //logs the number
    }   
    return 0;
}

Here is the arduino code:

#include <SoftwareSerial.h>

int i100;
int i10;
int i1;
int total;

void setup() {
  Serial.begin(1200);
  pinMode(2, OUTPUT);
}

void loop() {
int mail = Serial.available(); //reads number of available bytes
  if(mail >= 3) {
    int i100raw = Serial.read()-48; //reads 3 bytes and decodes from ASCII by subtracting 48
    int i10raw = Serial.read()-48;  
    int i1raw = Serial.read()-48; 

    if(i1raw >= 0) {  //checks if each byte is a valid input 
      i100 = i100raw; 
    }
    if(i10raw >= 0) {
      i10 = i10raw; 
    }
    if(i1raw >= 0) {
      i1 = i1raw; 
    }

    total = (i100*100)+(i10*10)+(i1); //puts together 3 digit number from 3 bytes

    while(total > 0) {       //flashes light  
      digitalWrite(2, HIGH);
      delay(50);
      digitalWrite(2, LOW);
      delay(50);
      total--;
    }   
  }
} 

Upvotes: 3

Views: 913

Answers (2)

Upfly
Upfly

Reputation: 11

Just met same issue and resolved. Set DTR to 1 will probably fix this issue.

arduino.DTR = YES;

Upvotes: 1

Rob
Rob

Reputation: 437642

A couple of thoughts:

  1. The main issue is that you're never setting the baudRate for ORSSerialPort. (You have that assignment backwards.) Also, the examples I've seen set the baud rate in ORSSerialPort before opening the port. So, I'd suggest:

    arduino.baudRate = @(1200); //sets baud rate
    [arduino open];             //opens port
    
  2. Also, in my test, if I tried closing the port to the Arduino immediately after writing the data, it would not be received. You might want to wait a bit before closing that port

  3. You might also want to use a new line terminator for what you send to the Arduino. That's obviously a change in both the sending and the receiving code, but it's going to be a little more robust than just reading the next three bytes.

  4. I might also suggest that if you want to be especially careful, you might want to set the delegate for the ORSSerialPort object and implement the ORSSerialPortDelegate methods. There is an error reporting method there that you might want to avail yourself of.

  5. When I begin my Serial on the Arduino, I include a loop that waits for the Serial to connect. The code snippet I took this from says this is only needed with Leonardo only, but it's worth trying if you're finding you cannot successfully receive data when you first open the connection from the Mac side:

    void setup() 
    {
      pinMode(2, OUTPUT);
    
      Serial.begin(1200); 
      while (!Serial) {
        // wait for serial port to connect. Needed for Leonardo only
      } 
    
      Serial.println("OK. Connected.");
    }
    

    Also, when your loop() successfully reads the input from Serial, you can have the Arduino write stuff back (via Serial.println) which you can have you Mac read in order to confirm successful receipt of the data. It's, effectively, a way of affirming receipt of the command and that will help you isolate communication related issues from wiring issues.

Upvotes: 1

Related Questions