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 | 16 | 0); THIS OPEN STATEMENT DIDN't WORK WELL

FILE *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/s

orb_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>

Views: 10335

Reply to This

Replies to This Discussion

I don't think so, cause the problem is how to get the data from Ardupilot

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

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,

Hello Alessandro and Gabriel,

             I have been pondering on this for more than 4 weeks now. uartA is used for Telemetry when MUX is left as it is. uartB is required for GPS. I think we shouldn't touch it as it will be required for safety operations. uartC is free. 

             I have also figured out to use MAVLink for communication

            The problem is how to insert code inside so many routines. We need to look at all codes and understand them before making any modifications. 

            It would be great if one of developers could comment on this? But I didn't get any reply on most of my previous query!!

             I have ordered pixhawk! May be I would be able to do something with this. 

Thanks guys!

Aak

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)

Thanks Parth! I got it working.

Hey guys! Sorry for being MIA for long.

We got our code to work ish.... We can send data using hal.uartB->printf(...) 

We are not using GPS, so uartB is available. The problem is that the funciton hal.uartB.available() does not seem to work - in other words, we can send data but we cannot receive it.

Thoughts? Did you managed to get things done with a pixhawk?

Good news guys! we finally got this to work.

Our project is not using GPS so we are using uartB - you could easily change to uartC as Parth said. 

\

[code]

//////////////////////////
// uartB communications //
//////////////////////////

//* Read info from BBB */
static struct {
int armMotors;
int pitch;
int yaw;
int roll;
int throttle;
int powerOff;
} receivedCommands;

void prepareUartB(){
hal.uartB->begin(9600);
receivedCommands.armMotors = 0;
receivedCommands.pitch = 0;
receivedCommands.yaw = 0;
receivedCommands.throttle = 0;
receivedCommands.powerOff = 0;
}

// Process the command in a switch statement. Returns 0 if processing fails
int processCommand(char * command){
char key = command[0];
int value = (command[1]-'0') * 1000 + (command[2]-'0') * 100 + (command[3]-'0') * 10 + (command[4]-'0') * 1;
switch(key){
case 'a':
case 'A':
//hal.uartB->printf("Changing armMotors to %d\n", value);
receivedCommands.armMotors = value;
if(value != 0 && flymode == auto_mode) { init_arm_motors(); }
else { init_disarm_motors(); }
return 1;
break;
case 'p':
case 'P':
//hal.uartB->printf("Changing Pitch to %d\n", value);
receivedCommands.pitch = value;
return 1;
break;
case 'r':
case 'R':
//hal.uartB->printf("Changing Roll to %d\n", value);
receivedCommands.roll = value;
return 1;
break;
case 'y':
case 'Y':
//hal.uartB->printf("Changing Yaw to %d\n", value);
receivedCommands.yaw = value;
return 1;
break;
case 't':
case 'T':
//hal.uartB->printf("Changing Throttle to %d\n", value);
receivedCommands.throttle = value;
return 1;
break;
case 'z':
case 'Z':
//hal.uartB->printf("Changing PowerOff to %d\n", value);
// TODO
receivedCommands.powerOff = value;
return 1;
break;
default:
hal.uartB->printf("Unknown command %c %d\n", key, value);
return 0;
break;
}
return 1;
}

/* Receives a message in the format S03 T1000 Y0000 R1234 */
void receiveMessage(void){
char start[3];
char command[5];
uint8_t data;
int num_commands = 0;
//hal.uartB->flush();
for(int ii = 0; ii < 5; ii++){
command[ii] = 'a';
}
//hal.uartB->printf("Message Received \n");
hal.gpio->write(AN7,HIGH);
for(int ii = 0; ii < 3; ii++){
data = hal.uartB->read();
while(!isValid( (char) data)){ data = hal.uartB->read(); }
start[ii] = (char) data;
}
if(start[0] == 's'){
if(isNumber(start[1])) num_commands = (start[1] - '0') * 10;
else hal.uartB->printf("Error in first command [1] \n");
if(isNumber(start[2])) num_commands += (start[2] - '0');
else hal.uartB->printf("Error in first command [2] \n");
hal.uartB->printf("Ready to receive %d commands. \n", num_commands);
} else {
hal.uartB->printf("Error in first command [0]. Got %s\n", start);
return;
}

// Receve the rest of the commands
while(num_commands--){
while(hal.uartB->available() == 0) {} // wait for new data
for(int ii = 0; ii < 5; ii++){
data = hal.uartB->read();
while(!isValid( (char) data)){ data = hal.uartB->read(); }
command[ii] = (char) data;
}
hal.uartB->printf("Command %d: %s \n", num_commands, command);
if(processCommand(command) == 0) hal.uartB->printf("Error parsing command!\n");
}
}

// TODO
void sendMessage(void){
Vector3f gyro, accel;
//Vector3f &compass_field, compass_offset; // .x .y .z
float b_voltage = battery.voltage();
float b_current = battery.current_amps();
float b_current_mah = battery.current_total_mah();
gyro = ins.get_gyro();
accel = ins.get_accel();
//compass.read();
const Vector3f &compass_field = compass.get_field();
//compass_offset = compass.get_offset();
hal.uartB->printf("sbv%fbc%fbm%f\ngx%fgy%fgz%f\nax%fay%faz%f\ncx%fxy%fcz%f\nmo%d\n", b_voltage, b_current, b_current_mah, gyro.x, gyro.y, gyro.z, accel.x, accel.y, accel.z, compass_field.x, compass_field.y, compass_field.z,flymode);
}

// Used for testing
void printStatustoUartB(void){
hal.uartB->printf("Status: Armed %d, Pitch %d, Yaw %d, Roll %d, Throttle %d, PowerOff %d\n", receivedCommands.armMotors, receivedCommands.pitch, receivedCommands.yaw, receivedCommands.roll, receivedCommands.throttle, receivedCommands.powerOff);
}

void sync_uart(void){
int num = hal.uartB->available();
if(num > 0){
hal.gpio->write(AN7,HIGH);
receiveMessage();
sendMessage();
//printStatustoUartB();
} else {
hal.gpio->write(AN7,LOW);
}
}

[/code]

Some of the variables we have are for our purpose specific project but you get the idea. This allows you to send data back and forth - what you do with the data is up to you

PS - I tried formating this post but I am not sure how

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.

Reply to Discussion

RSS

Groups

Season Two of the Trust Time Trial (T3) Contest 
A list of all T3 contests is here. The current round, the Vertical Horizontal one, is here

© 2019   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service