Reputation: 31
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
Reputation: 11
Just met same issue and resolved. Set DTR to 1 will probably fix this issue.
arduino.DTR = YES;
Upvotes: 1
Reputation: 437642
A couple of thoughts:
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
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
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.
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.
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