Simple C or C++ example for Raspberry?
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Simple C or C++ example for Raspberry?
So I edited your post to add the BBCode. This displays the text in a code block which is much easier to read.
I see two problem.
1. The Peek command is trying to open the port again. I dont think its being used so it probably doesnt matter but thought I better point it out.
2. It looks like you are sending decimal 80 for the Roboclaw address instead of 0x80(eg hexidecimal). Also the ReadVersion command is hexidecimal 0x15 not decimal 15(its decimal 21). This is probably the main problem with your program.
Code: Select all
I see two problem.
1. The Peek command is trying to open the port again. I dont think its being used so it probably doesnt matter but thought I better point it out.
2. It looks like you are sending decimal 80 for the Roboclaw address instead of 0x80(eg hexidecimal). Also the ReadVersion command is hexidecimal 0x15 not decimal 15(its decimal 21). This is probably the main problem with your program.
Re: Simple C or C++ example for Raspberry?
cool.. btw - whenever I have tried to wrap anything with the formatting tags (like the code tags), when I do a preview or a submit, I get back a blank editor box saying 'too few characters'. I remove the tags, and it all shows up again.
the peek() - yeah, I had thought at first it was the cause of the 'device temp busy' but it doesnt seem to be - but if it's not being used, all the better.
Question, though: how would be a good way to do a peek? Related - should the port read() be blocking or non-blocking... ? I guess that's why I thought the peek() was necessary. (well there IS the available() )
I will change over to hex (sorry I should have seen that).
thanks
the peek() - yeah, I had thought at first it was the cause of the 'device temp busy' but it doesnt seem to be - but if it's not being used, all the better.
Question, though: how would be a good way to do a peek? Related - should the port read() be blocking or non-blocking... ? I guess that's why I thought the peek() was necessary. (well there IS the available() )
I will change over to hex (sorry I should have seen that).
thanks
Re: Simple C or C++ example for Raspberry?
Hi,
I don't think it's the issue of hex vs decimal. see below.
Could it be I need to set start/stop bits, parity..etc.. I was confused in the manual.. because it talks about serial and packet serial...
Here is test output:
Hopefully these links to code will now work:
complete test output (not much diff from above):
https://github.com/elicorrales/roboclaw ... boclaw.log
main():
https://github.com/elicorrales/roboclaw ... c/main.cpp
RoboClaw:
https://github.com/elicorrales/roboclaw ... boClaw.cpp
HardwareSerial:
https://github.com/elicorrales/roboclaw ... Serial.cpp
I don't think it's the issue of hex vs decimal. see below.
Could it be I need to set start/stop bits, parity..etc.. I was confused in the manual.. because it talks about serial and packet serial...
Here is test output:
Code: Select all
RoboClaw::RoboClaw()
RoboClaw::begin()
HardwareSerial::hwSerialBegin(9600)
inSpeed : 13
outSpeed : 13
inSpeed : 13
outSpeed : 13
RoboClaw::ReadVersion()
RoboClaw::flush()
HardwareSerial::hwSerialFlush()
RoboClaw::crc_clear()
RoboClaw::write()
HardwareSerial::hwSerialWrite(%x=80 %d=128)
RoboClaw::crc_update()
RoboClaw::write()
HardwareSerial::hwSerialWrite(%x=15 %d=21)
RoboClaw::crc_update()
RoboClaw::ReadVersion():for loop(0)
RoboClaw::ReadVersion():gna read()...
RoboClaw::read( timeout)
RoboClaw::ReadVersion():read():data = %x= ff %d=255
RoboClaw::crc_update()
RoboClaw::ReadVersion():for loop(1)
RoboClaw::ReadVersion():gna read()...
RoboClaw::read( timeout)
RoboClaw::ReadVersion():read():data = %x= ff %d=255
RoboClaw::crc_update()
Hopefully these links to code will now work:
complete test output (not much diff from above):
https://github.com/elicorrales/roboclaw ... boclaw.log
main():
https://github.com/elicorrales/roboclaw ... c/main.cpp
RoboClaw:
https://github.com/elicorrales/roboclaw ... boClaw.cpp
HardwareSerial:
https://github.com/elicorrales/roboclaw ... Serial.cpp
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Simple C or C++ example for Raspberry?
Virtual serial ports(eg ttyACM0) do not need baudrate settings or format usually. If you are concerned that is the case set 8N1 and whatever baudrate you set using Ion Studio, Roboclaw defaults to 38400). Note that some computers Virtual serial ports may not work correctly if you dont set the baudrate to something(eg non-zero).
I recommend you back up and write a simple test program that sends 0x80, 0x15 and reads back any bytes that come in to see if you can figure if its a serial port problem.
Something is definitely wrong with your code but I cant see what. You are apparently receiving actual 0xFF bytes or your PC is lying to you and you are not receiving any data back and its just returning 0xFF from the hwSerialRead no matter what the state of the serial buffer is.
I recommend you back up and write a simple test program that sends 0x80, 0x15 and reads back any bytes that come in to see if you can figure if its a serial port problem.
Something is definitely wrong with your code but I cant see what. You are apparently receiving actual 0xFF bytes or your PC is lying to you and you are not receiving any data back and its just returning 0xFF from the hwSerialRead no matter what the state of the serial buffer is.
Re: Simple C or C++ example for Raspberry?
ok, learned a bit more.
program output:
Code at bottom, but essential, I don't think it's reading anything.
I did set the baud to 9600 via Ion Studio.
I also did an stty at Raspberry terminal, here's the results:
Here's the code, all in a single file:
program output:
Code: Select all
hwSerialBegin(9600)
inSpeed : 1
outSpeed : 1
inSpeed : 13
outSpeed : 13
Writing 0x80......
Writing 0x15......
doing read loop......
seeing if bytes available......
. seeing if bytes available......
. seeing if bytes available......
. seeing if bytes available......
. seeing if bytes available......
I did set the baud to 9600 via Ion Studio.
I also did an stty at Raspberry terminal, here's the results:
Code: Select all
sudo stty -F /dev/ttyACM0
speed 9600 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = ^\; eof = M-H; eol = M-^T; eol2 = 1; start = @; stop = M-}; susp = v; rprnt = M-F; werase = ~; lnext = M-h; discard = M-=; min = 126; time = 189;
-cread
-brkint -icrnl ixoff -imaxbel
-opost ocrnl ofill ofdel cr3 vt1
-isig -icanon -echo noflsh echoprt -echoke flusho
Code: Select all
#include <iomanip>
#include <termios.h>
#include <iostream>
#include <sstream>
#include <errno.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <wiringPi.h>
#include <iomanip>
#include <termios.h>
using namespace std;
const string _serialDeviceName = "/dev/ttyACM0";
void hwSerialHandleError(const string& message, int errnum) {
ostringstream msgstream("");
msgstream << message << " : " << _serialDeviceName << " : ";
if (errnum) {
msgstream << "errno is [ " << errnum << "] : " << strerror(errnum);
}
msgstream << '\n';
cerr << msgstream.str();
exit(1);
}
int main(int argc, char** argv) {
int _fd = open(_serialDeviceName.c_str(),O_RDWR | O_NOCTTY );
if (1 > _fd or 0 != errno) {
hwSerialHandleError("Error opening",errno);
}
int speed = 9600;
cout << "hwSerialBegin(" << speed << ")\n";
struct termios _settings;
speed_t inSpeed = cfgetispeed(&_settings);
speed_t outSpeed = cfgetospeed(&_settings);
cout << "inSpeed : " << inSpeed << '\n';
cout << "outSpeed : " << outSpeed << '\n';
switch (speed) {
case 4800:
cfsetispeed(&_settings,B4800);
cfsetospeed(&_settings,B4800);
break;
case 9600:
cfsetispeed(&_settings,B9600);
cfsetospeed(&_settings,B9600);
break;
case 19200:
cfsetispeed(&_settings,B19200);
cfsetospeed(&_settings,B19200);
break;
case 38400:
cfsetispeed(&_settings,B38400);
cfsetospeed(&_settings,B38400);
break;
case 115200:
cfsetispeed(&_settings,B115200);
cfsetospeed(&_settings,B115200);
break;
}
tcsetattr(_fd,TCSANOW,&_settings);
delay(200);
inSpeed = cfgetispeed(&_settings);
outSpeed = cfgetospeed(&_settings);
cout << "inSpeed : " << inSpeed << '\n';
cout << "outSpeed : " << outSpeed << '\n';
cout << "Writing 0x80......\n";
uint8_t byte = 0x80;
errno = 0;
int bytesWritten = write(_fd,&byte,sizeof(byte));
if (1>bytesWritten) {
hwSerialHandleError("Error writing 0x80",errno);
}
delay(10);
cout << "Writing 0x15......\n";
byte = 0x15;
errno = 0;
bytesWritten = write(_fd,&byte,sizeof(byte));
if (1>bytesWritten) {
hwSerialHandleError("Error writing 0x15",errno);
}
cout << "doing read loop......\n";
for (int i=0;i<1000;i++) {
delay(10);
cout << "\t seeing if bytes available......\n";
errno = 0;
uint8_t bytes = 0;
int rtn = ioctl(_fd,FIONREAD, &bytes);
if (0 < rtn and 0 == errno and bytes > 0) {
cout << "\t\t there is, lets get it......\n";
int byte = 0;
errno = 0;
int bytesRead = read(_fd,&byte,sizeof(byte));
if (0 > bytesRead or 0 != errno) {
hwSerialHandleError("Error Reading Byte",errno);
}
cout << "[" << byte << "]";
} else {
cout << ". ";
}
}
cout << '\n';
return 0;
}
Re: Simple C or C++ example for Raspberry?
I also tried this:
same result
Code: Select all
cout << "Writing 0x80,0x15......\n";
uint8_t bytes[2] = { 0x80, 0x15 };
errno = 0;
int bytesWritten = write(_fd,&bytes,2*sizeof(uint8_t));
if (1>bytesWritten) {
hwSerialHandleError("Error writing 0x80",errno);
}
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Simple C or C++ example for Raspberry?
1.Confirm the Roboclaw is working correctly with Ion Studio.
2.Confiurm you have the latest firmware(4.1.24)
3.Reset the Roboclaw to default settings using Ion Studio
4.Download and test reading the version using our Python library examples. This will confirm the RPi is able to talk to the Roboclaw and let us know the problem is in the serial port access in the C/C++ program.
Let me know the results.
2.Confiurm you have the latest firmware(4.1.24)
3.Reset the Roboclaw to default settings using Ion Studio
4.Download and test reading the version using our Python library examples. This will confirm the RPi is able to talk to the Roboclaw and let us know the problem is in the serial port access in the C/C++ program.
Let me know the results.
Re: Simple C or C++ example for Raspberry?
Yes..
1) Roboclaw works with Ion Studio
2) Has latest firmware
3) will try the 'reset'
4) I'm also having Python issues - will tackle that part later, BUT - I already confirmed the Raspberry Pi + serial port does work by taking someone else's code. However, I don't want to use that code because it depends on Boost C++ and that's a really heavy / bloated library
So it has to be my code.
I will see what else I can figure out over the weekend
thanks for all the help...
1) Roboclaw works with Ion Studio
2) Has latest firmware
3) will try the 'reset'
4) I'm also having Python issues - will tackle that part later, BUT - I already confirmed the Raspberry Pi + serial port does work by taking someone else's code. However, I don't want to use that code because it depends on Boost C++ and that's a really heavy / bloated library
So it has to be my code.
I will see what else I can figure out over the weekend
thanks for all the help...
Re: Simple C or C++ example for Raspberry?
Hi,
I tried the following, and it works, however it uses Boost.
I tried the following, and it works, however it uses Boost.
Code: Select all
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
string serialDev = "/dev/ttyACM0";
boost::asio::io_service io;
boost::asio::serial_port serial(io, serialDev);
string getVersion()
{
uint8_t commands[] = { 0x80, 0x15 };
write( serial, boost::asio::buffer(commands, 2));
// read the result
string ver = "";
char c = 0;
bool reading = true;
while( reading )
{
boost::asio::read(serial,boost::asio::buffer(&c,1));
switch(c)
{
case '\0':
// also read the crc
boost::asio::read(serial,boost::asio::buffer(&c,1));
boost::asio::read(serial,boost::asio::buffer(&c,1));
reading = false;
break;
default:
ver+=c;
}
}
return ver;
}
int main( int argc, char** argv )
{
cout << "version : " << getVersion() << endl;
return 0;
}
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Simple C or C++ example for Raspberry?
For now that may be your only option until we can get to writing our own C/C++ Linux library. Serial Port access is the sticking point with C/C++ since its not inherently built in.
Python at least has pyserial. Make sure you use Python 2.7 with our python library. It is not written for Python 3.
Python at least has pyserial. Make sure you use Python 2.7 with our python library. It is not written for Python 3.