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?
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
}
}
}
}
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