Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a serial port with arduino using c++ with Xcode on mac

I've written a simple program in c++ which sends an angle value to an Arduino through a serial port; the Arduino than uses the value to control a servo motor.

This is c++ code

#include <iostream>
#include <unistd.h>
#include <fstream>

using namespace std;

int main()
{
    unsigned int angle;
    fstream arduino;
    
    cout<<"check-1";

    arduino.open("/dev/tty.usbmodem3a21");

    cout<<"check-2";
    
    if(arduino)
    {
        do
        {
            cout<<"\n\ninsert a number between 0 and 179";
        
            cin>>angle;
            arduino<<angle;
            
        }while(angle <= 179);
        
        arduino.close();
    }
    else
    {
        cout<<"\n\nERROR!!\n\n";
    }
    
    
}

and this is arduino's:

#include <Servo.h>

Servo servo;
const int pinServo = 2;
unsigned int angle;

void setup()
{
    Serial.begin(9600);
    servo.attach(pinServo);
    
    servo.write(0);
    
}

void loop()
{
    if(Serial.available()>0)
    {  
       angle = Serial.read();
       
       if(angle <= 179)
       {
         servo.write(angle);
       }
    }
}

The problem is that it stops at arduino.open(...). Despite I checked that the selected port in the Arduino app in tools > serial port is correct, it doesn't even print out "check-1".

To add more useful information, I tested opening the port with the iOS::binary parameter so the opening command becomes arduino.open("/dev/tty.usbmodem3a21",iOS::binary); as a result, this prints out "check-1", "check-2" and "ERROR!!". I get the same results if I type in a wrong serial port name.

Why is this happening and how do I fix this?

like image 977
Dadda Barba Avatar asked Nov 10 '22 21:11

Dadda Barba


1 Answers

The arduino shows up as a serial device. You should look at using the open() and close() function. I've done this on Linux but I'm pretty sure this works similarly on Mac. This is an example snippet of code. The first snippet opens and sets up the file descriptor.

int fd;                             // File descriptor
// Open port
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1){
    printf("Device cannot be opened.\n");
    exit(-1);                       // If the device is not open, return -1
}
struct termios options;

fcntl(fd, F_SETFL, FNDELAY);                    // Open the device in nonblocking mode

// Set parameters
tcgetattr(fd, &options);                        // Get the current options of the port
bzero(&options, sizeof(options));               // Clear all the options
speed_t         Speed;
switch (baudRate)                               // Set the speed (baudRate)
{
    case 110  :     Speed=B110; break;
    case 300  :     Speed=B300; break;
    case 600  :     Speed=B600; break;
    case 1200 :     Speed=B1200; break;
    case 2400 :     Speed=B2400; break;
    case 4800 :     Speed=B4800; break;
    case 9600 :     Speed=B9600; break;
    case 19200 :    Speed=B19200; break;
    case 38400 :    Speed=B38400; break;
    case 57600 :    Speed=B57600; break;
    case 115200 :   Speed=B115200; break;
    default : exit(-4);
}
cfsetispeed(&options, Speed);                   // Set the baud rate at 115200 bauds
cfsetospeed(&options, Speed);
options.c_cflag |= ( CLOCAL | CREAD |  CS8);    // Configure the device : 8 bits, no parity, no control
options.c_iflag |= ( IGNPAR | IGNBRK );
options.c_cc[VTIME]=0;                          // Timer unused
options.c_cc[VMIN]=0;                           // At least on character before satisfy reading
tcsetattr(fd, TCSANOW, &options);               // Activate the settings

This just closes it:

close(fd); 

To read from the actual file descriptor:

ioctl(fd, FIONREAD, &t1);                           
if(t1 > 0) {
    // If the number of bytes read is equal to the number of bytes retrieved
    if(read(fd,pByte, t1) == t1) {  
        for(int i =0; i < t1; i++) {
            if(pByte[i] != '\r'){ // Just makes sure you're not scanning new lines
                // TODO: Do what you want with this character
            }
        }
    }
}
like image 122
Ajay Avatar answered Nov 14 '22 23:11

Ajay