2
votes

I wrote a code to connect, throught a serial port, mi computer to arduino.

This is arduino's code:

#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);
       }
    }
}

And this is c++'s:

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

using namespace std;

int main()
{
    unsigned int angle;
    ofstream arduino;
    struct termios ttable;

    cout<<"\n\ntest1\n\n";

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

    cout<<"\n\ntest2\n\n";

    if(!arduino)
    {
        cout<<"\n\nERR: could not open port\n\n";
    }
    else
    {
        if(tcgetattr(arduino,&ttable)<0)
        {
            cout<<"\n\nERR: could not get terminal options\n\n";
        }
        else
        {
            ttable.c_cflag &= ~PARENB;
            ttable.c_cflag &= ~CSTOPB;
            ttable.c_cflag &= ~CSIZE;
            ttable.c_cflag |= CS8;
            ttable.c_cflag &= ~CRTSCTS;
            ttable.c_cflag |= CREAD | CLOCAL;
            ttable.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
            ttable.c_oflag &= ~OPOST;
            ttable.c_cc[VMIN]  = 0;
            ttable.c_cc[VTIME] = 0;

            cfsetospeed(&ttable,9600);

            if(tcsetattr(arduino,TCSANOW,&ttable)<0)
            {
                cout<<"\n\nERR: could not set new terminal options\n\n";
            }
            else
            {
                do
                {
                    cout<<"\n\ninsert a number between 0 and 179";
                    cin>>angle;
                    arduino<<angle;
                }while(angle<=179);

                arduino.close();
            }
        }
    }

}

It should connect to arduino , then ask me a number between 0 an 179 and the send that number to arduino which aplly that number as an angle to a servo motor; But it stops at arduino.open("/dev/tty.usbmodem3a21") .What can i do ?

1
What do you mean "it stops"? Do you get an exception, or does the program hang? Can you elaborate about the actual behavior please.πάντα ῥεῖ
Sorry.it compliles , no errors no warnings, then it execute by terminal and i see the output "test1" and then the program stops , after "test1" there's no output, no text, nothing . And i also know for sure that is not a matter of time.Dadda Barba
When you say "it stops" do you get the shell prompt back? Also note you should use std::endl instead of "\n" for line endings. You might miss outputs, unless they're flushed (that's what std::endl does addtitionally vs outputting "\n").πάντα ῥεῖ
No , i think "it freeze" make a better idea, the terminal remains opened , the program continues to run, but there is nothing as outputDadda Barba
I'm more and more conviced that the tcgetattr(arduino,&ttable) causes the problem. Remember that ofstream has an automatic conversion to bool and thus to int. Supposed the open was good, you're passing 1 as fd parameter effectively, and change the attributes of stdin fd. Use the raw c-style open() to obtain an fd for your arduino device.πάντα ῥεῖ

1 Answers

2
votes

I think your problems appear in these lines of code

if(tcgetattr(arduino,&ttable)<0) {
    // ...
}
else {
    // ...

    if(tcsetattr(arduino,TCSANOW,&ttable)<0) {
        // ...
    }
}

The arduino variable is of type ofstream, where tcgetattr() and tcsetattr() expect a file descriptor obtained with open() at this point.

ofstream provides an automatic conversion to bool and thus int implicitely. Supposed the

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

went OK, you are effectively passing 1 to tcgetattr() and tcsetattr(), which is the standard input file descriptor.


Solution is not to use a ofstream for arduino, but an ordinary file descriptor

int arduino = open("/dev/tty.usbmodem3a21",O_WRONLY);