on a unix based software, which must send a number between 0 and 179 to arduino and arduino will apply that number as an angle to a servo motor, but i do not know what parameters i have to change in the terminos struct to permit the serial communication.
this is the c++ code:
#include <iostream>
#include <unistd.h>
#include <fstream>
#include <termios.h>
using namespace std;
int main()
{
unsigned int angle;
ofstream arduino;
struct termios ttable;
//cout<<"test-1";
arduino.open("/dev/tty.usbmodem3a21");
//cout<<"test-2";
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
{
//there goes the terminal options setting for the output;
ttable.c_cflag = -hupcl //to prevent the reset of arduino
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();
}
}
}
}
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);
}
}
}
So would you kindly tell me what do i have to change of "ttable" ?
In general, talking to an Arduino from C/C++ is easiest with the serial port in 'raw' mode. This is basically 8N1, byte-at-a-time, with the TTY doing the minimal amount of futzing about with the data. An easy way to set the various flags in a termios struct for this mode is to use cfmakeraw(3). Per the man pages this does the following:
struct termios config;
config.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
INLCR | IGNCR | ICRNL | IXON);
config.c_oflag &= ~OPOST;
config.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
config.c_cflag &= ~(CSIZE | PARENB);
config.c_cflag |= CS8;
For good measure, explicitly set receive enable and ignore modem control with config.c_cflag |= (CLOCAL | CREAD);. If the termios structure you are using is a copy of the existing one (obtained with tcgetattr(), for example), then also disable flow control altogether with config.c_iflag &= ~(IXOFF | IXANY);. So all-in-all, it will look like:
struct termios config;
cfmakeraw(&config);
config.c_cflag |= (CLOCAL | CREAD);
config.c_iflag &= ~(IXOFF | IXANY);
// set vtime, vmin, baud rate...
config.c_cc[VMIN] = 0; // you likely don't want to change this
config.c_cc[VTIME] = 0; // or this
cfsetispeed(&config, B9600);
cfsetospeed(&config, B9600);
// write port configuration to driver
tcsetattr(fd, TCSANOW, &config;
Using C++ file streams is a bit tricky as well. You very likely want non-blocking read/write and no controlling TTY, so it is usually easier to use open(2) with the O_NOCTTY and O_NDELAY flags set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With