So guys, I'm doing a project related to Telemetry, and I want to make ArduPilot (Uploaded with ArduPlane 2.73) send through Serial Port, The sensors informations, like Height, GPS Position, and this kind of things. I have tried to use ArduStation, but I could not change its firmware to do what I want.
The idea is reading Ardupilot Serial port using an Arduino Uno, and then, saving it in a SD card in real-time. So ArduPilot needs to send data without any User Input or something like that. I've already tried to manipulate ArduPlane source code to do that, but I couldn't either.
Has someone here did something like that before? I need some advices!
Thanks,
Alessandro
alessandro.ssj@gmail.com
EDIT (30/06/2016) : Guys, I've successfully done the communication of Pixhawk with Arduino through Pixhawk's UART. So I can send informations of the pixhawk's IMU to arduino or any other microcontroller through serial PORT. So, if you want any help, I don't follow this post anymore, so send me an e-mail (alessandro.ssj@gmail.com) and I can help with some details.
EDIT(08/06/2017): So, since I've been receiving lots of emails about this issue, I will clarify here a little more.
The communication was from the arduino to the pixhawk through serial communication (and the inverse communication is straight forward). In the code shown below, the port TELEM2 is used.
The idea was to read a single byte of the serial port and wait for a flag, that was the character 'a' sent by an arduino ( I was communicating the Pixhawk with an arduino). So, when it detects an a, it starts to reads the rest of bytes until the flag 'b', which indicates end of transmission, arrives. The code below implements this idea:
int arduino_thread_main(int argc, char *argv[])
{
running = true;
struct arduino_s data;
char buffer[50];
int c; int i;// Advertise arduino topic
memset(&data, 0 , sizeof(data));//Open serial communication with Arduino
//ttyACM0=USB cable; ttyS1= TELEM1; ttyS2=TELEM2
//int fd=open("/dev/ttyS2", O_RDWR | 1<<6 | 0); THIS OPEN STATEMENT DIDN't WORK WELLFILE *fd=fopen("/dev/ttyS2","r"); // Open Serial communication through TELEM 2
orb_advert_t arduino_pub_fd = orb_advertise(ORB_ID(arduino), &data); // Advertise arduino uORB
while(!should_exit){
float rpm_hall=-1.0f; float rpm_motor=-1.0f; i=0;while ((c=fgetc(fd)) !='\n') {buffer[i++] = c;} // Construct string from serial comm. c = fgetc(fd) do the magic!
buffer[i]='\0'; // Finish the construction of the string
sscanf(buffer,"h%fr%fe",&rpm_hall,&rpm_motor); // Read separated date using the protocol defined as "hDATAFLOATrDATAFLOATe"
data.hall=(double)rpm_hall*(M_PI/30.0); // in rad/s
data.rpm= (double)rpm_motor*(M_PI/30.0); // in rad/sorb_publish(ORB_ID(arduino),arduino_pub_fd,&data); // Publish information
}
fclose(fd);
running = false;
return 0;
}
Another issue people are asking me, is how to get pixhawk sensors information (like pitch, yaw, altitude and so on) and do something with it (save in a SD card for example).
Years ago I made a code to translate the ORB protocol used in pixhawk to access the sensors data, to a more friendly way. You can find the code here:
https://github.com/alessandroSSJ/AeroPixHawk/
Thanks!
Alessandro Soares da Silva Junior - PUC-Rio<\p>
Replies
I realize this is an old thread, but maybe someone can help me. I'm also trying to download telemetry data directly from a Pix/Mavlink USB/Serial port and dump the data to a file. I have this working with Mavproxy, but they delay and latency make it near useless. This is on a Raspberry PI Zero w/ Debian Jessie. I have compiled a couple C++ codes from examples, but I can't obtain the data I want. Here is how it should work.
1. Connect to PIX/Mavlink via /dev/ttyACM0 port.
2. Download several pieces of telemetry data (GPS, Alt, Speed, Etc) and save them to a local file on the RPI
3. Repeat, Repeat, Repeat...
Near real time speed is critical. I could define the telemetry options either in the C++ source or pass them as parameters.
Any help would be GREATLY appreciated.
Thx,
Dave M
Hello Alessandro,
I am working on a similar project. The idea is to control the ArduCopter with an on board BeagleBone. I am trying to figure out how to send commands from one to the other. Did you ever figure out how to send data through serial? And also, how to receive it?
Best,
Hello Gabriel,
The code of ArduPilot that can be found in googlecode is, in my opinion, a mess. So it would take a long time in order to find where I should modificate it to do the things i wanted. Considering this, I've started to study the code of PX4, and in a short period of time (like two days) i was able to make any modification i wanted.
So my advice is, if you really want to communicate with BeagleBone, buy a PX4 (Or Pixhawk), study its code and you will be able to make serial communication easily!
For example, I make PX4 send through one of its UART, Pitch Angle, Roll Angle, Yaw Angle, Height and groundspeed of the airplane in a chosen baud rate and everything had worked fine!
Good Luck, send me a message if you need more help!
Alessandro
Alessandro, I have been studying the PX4 code and haven't made a lot of progress. Can you give me some detail on how you were able to send data through a UART.
It seems all the tutorials and info about accessing the serial ports have been taken down.
Thanks for any help you can provide!
Bill
Hey @Alessandro - would you perhaps still have the code you used to have the PX4 send those values through it's UART? I am trying to do something similar, where I read PWM values that I am trying to print on the UART and read it via a microcontroller. As of now, all I get is "blank"
uint8_t nchannels = hal.rcin->num_channels();
for (uint8_t i=0; i<nchannels; i++)
{
uint16_t v = hal.rcin->read(i);
hal.uartE->printf("Channel: %d Output: %d \n",i, v);
}
The above should send channel data and I should be able to read at the UART, right? But this doesn't do anything.
Hello Alessandro,
Thank you for responding to my post.
Unfortunately, I am working with a team on this project and we are constrained to using the ArduPilot ... I have been looking at the code and it is a mess. The code is really well written, but its a pain to edit. We have managed to add some features but we have not managed to get the Serial to work...
Right now the idea is to use uartB (used for GPS) but we are still thinking about it.
Best,
UartC is available on the apm 2.5. I connected an FTDI cable to the serial pins labeled uart2 and sent print statements on uartC.
Hi Parth,
Could you please explain with an example? I did similar thing but didn't work. First I connected TX2, RX2, +5V and GND pins (PINS 5,6,7 and 8) below reset button of ArduPilot2.5 to my LinuX computer. I used hal.uartC->write(1) inside void loop() function of ArduPlane.pde file. This didn't work :( . Do we need to modify any other file?
Thank you for your help.
Best Regards,
Aak
The syntax is same as regular arduino code...Add hal.uartC->begin(baudrate) to void setup.
Use hal.uartC->println("hello") or whatever you need to print out in the loop block. Don't connect the +5v pin, power is not needed (assuming that you are connected with USB already)
Hi Parth,
As I was trying to connect the UT390B laser rangefinder to the APM, I tried the following code but it does not work:
#include <AP_Common.h>
#include <AP_Math.h>
#include <AP_Param.h>
#include <AP_Progmem.h>
#include <AP_HAL.h>
#include <AP_HAL_AVR.h>
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
static uint32_t millis()
{
return hal.scheduler->millis();
}
static uint32_t t1 = 0;
void setup() {
hal.uartC->begin(115200, 256, 256);
hal.uartC->set_blocking_writes(false);
hal.uartC->println("*00084553#");
}
void loop() {
if (hal.uartC->is_initialized() == false) {
hal.console->printf_P(PSTR("uartC is not initialised\r\n"));
}
if (millis() > t1 + 3000) {
hal.console->printf_P(PSTR("Sending restart sequence..\r\n"));
hal.uartC->println("*00084553#");
t1 = millis();
}
hal.scheduler->delay(1);
}
AP_HAL_MAIN();
But the following code in Arduino works:
void setup() {
// put your setup code here, to run once:
Serial2.begin(115200);
}
static unsigned long t1 = 0;
void loop() {
if (millis() > (t1 + 10000)) {
Serial2.write("*00084553#");
t1 = millis();
}
}
Could you please help me to find out why? Thanks.