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