fdivitto / MSP

Arduino MSP (MultiWii Serial Protocol) library
GNU Lesser General Public License v2.1
48 stars 19 forks source link

an exemple to test #2

Open youceforo opened 6 years ago

youceforo commented 6 years ago

hello, I am just beguinner in programation ,I ask you if you can help me , I want to use your MSP library or others to show some paramteres (like altitude..... ) in MULTIWII GUI using an arduino nano ,so ,can you at least give me an exemple to test ?

aitordnb commented 6 years ago

Hello,

I also would be interested on a couple of examples for most common operations with MSP protocol.

Thanks a lot @fdivitto for your work!

virtualfish commented 5 years ago

Hi I am using your code to communicate with my Inav quadcopter using Arduino Uno and I can succesfully read ATTITUDE data, RC stick position and Analog port values. All work very well but I need support as I am stuck on using the following high level funtion:

 bool MSP::getActiveModes(uint32_T activeModes)

All I get at the pointer *activeModes is a value of 131 Can you please show me how to use this function and what kind of data will I get in the activeModes variable?

This is my Arduino project:

#include "msp.h"
#include <SoftwareSerial.h>
MSP msp;

SoftwareSerial mspSerial(11, 12); // RX TX for MSP
SoftwareSerial mySerial(9, 10);
void setup()
{
  mySerial.begin(19200);
  mspSerial.begin(19200);
  msp.begin(mspSerial);
}

void loop()
{
  msp_rc_t rc;
  msp_attitude_t attitude;
  msp_analog_t analog;
  _delay_ms(500);
  uint32_t * activeModes;
  if (msp.request(MSP_ANALOG, &analog, sizeof(analog))) {
    uint8_t  vbat     = analog.vbat;     // 0...255
    uint16_t mAhDrawn = analog.mAhDrawn; // milliamp hours drawn from battery
    uint16_t rssi     = analog.rssi;     // 0..1023
    int16_t  amperage = analog.amperage; // send amperage in 0.01 A steps, range is -320A to 320A  
    mySerial.print("Batteria: " + String(vbat/10.0));
    mySerial.print(" mAh: " + String(mAhDrawn));
    //mySerial.print(" RSSI: " + String(rssi));
    mySerial.println(" A: " + String(amperage/100.0));
  }

  if (msp.request(MSP_RC, &rc, sizeof(rc))) {
    uint16_t roll     = rc.channelValue[0];
    uint16_t pitch    = rc.channelValue[1];
    uint16_t yaw      = rc.channelValue[2];
    uint16_t throttle = rc.channelValue[3];
    mySerial.print("RC-Roll: " + String(roll));
    mySerial.print(" RC-Pitch: " + String(pitch));
    mySerial.print(" RC-Throttle: " + String(throttle));
    mySerial.println(" RC-Yaw: " + String(yaw));
  }

  if (msp.request(MSP_ATTITUDE, &attitude, sizeof(attitude))) {
    int16_t roll     = attitude.roll;
    int16_t pitch    = attitude.pitch;
    uint16_t yaw      = attitude.yaw;
    mySerial.print("Att-Roll: " + String(roll/10.0));
    mySerial.print(" Att-Pitch: " + String(pitch/10.0));
    mySerial.println(" Att-Yaw: " + String(yaw));
  }

    msp.getActiveModes(*activeModes);         //
    mySerial.println(String(*activeModes));   //This line does not work!!
}

and the output:

Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.40 Att-Pitch: -1.40 Att-Yaw: 193 131 Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.30 Att-Pitch: -1.40 Att-Yaw: 193 131 Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.30 Att-Pitch: -1.40 Att-Yaw: 193 131 ...

and so on.

Can you tell me what is wrong with the above code? Please reply. Greetings!

tfmo18 commented 5 years ago

Hi I am using your code to communicate with my Inav quadcopter using Arduino Uno and I can succesfully read ATTITUDE data, RC stick position and Analog port values. All work very well but I need support as I am stuck on using the following high level funtion:

 bool MSP::getActiveModes(uint32_T activeModes)

All I get at the pointer *activeModes is a value of 131 Can you please show me how to use this function and what kind of data will I get in the activeModes variable?

This is my Arduino project:

#include "msp.h"
#include <SoftwareSerial.h>
MSP msp;

SoftwareSerial mspSerial(11, 12); // RX TX for MSP
SoftwareSerial mySerial(9, 10);
void setup()
{
  mySerial.begin(19200);
  mspSerial.begin(19200);
  msp.begin(mspSerial);
}

void loop()
{
  msp_rc_t rc;
  msp_attitude_t attitude;
  msp_analog_t analog;
  _delay_ms(500);
  uint32_t * activeModes;
  if (msp.request(MSP_ANALOG, &analog, sizeof(analog))) {
    uint8_t  vbat     = analog.vbat;     // 0...255
    uint16_t mAhDrawn = analog.mAhDrawn; // milliamp hours drawn from battery
    uint16_t rssi     = analog.rssi;     // 0..1023
    int16_t  amperage = analog.amperage; // send amperage in 0.01 A steps, range is -320A to 320A  
    mySerial.print("Batteria: " + String(vbat/10.0));
    mySerial.print(" mAh: " + String(mAhDrawn));
    //mySerial.print(" RSSI: " + String(rssi));
    mySerial.println(" A: " + String(amperage/100.0));
  }

  if (msp.request(MSP_RC, &rc, sizeof(rc))) {
    uint16_t roll     = rc.channelValue[0];
    uint16_t pitch    = rc.channelValue[1];
    uint16_t yaw      = rc.channelValue[2];
    uint16_t throttle = rc.channelValue[3];
    mySerial.print("RC-Roll: " + String(roll));
    mySerial.print(" RC-Pitch: " + String(pitch));
    mySerial.print(" RC-Throttle: " + String(throttle));
    mySerial.println(" RC-Yaw: " + String(yaw));
  }

  if (msp.request(MSP_ATTITUDE, &attitude, sizeof(attitude))) {
    int16_t roll     = attitude.roll;
    int16_t pitch    = attitude.pitch;
    uint16_t yaw      = attitude.yaw;
    mySerial.print("Att-Roll: " + String(roll/10.0));
    mySerial.print(" Att-Pitch: " + String(pitch/10.0));
    mySerial.println(" Att-Yaw: " + String(yaw));
  }

    msp.getActiveModes(*activeModes);         //
    mySerial.println(String(*activeModes));   //This line does not work!!
}

and the output:

Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.40 Att-Pitch: -1.40 Att-Yaw: 193 131 Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.30 Att-Pitch: -1.40 Att-Yaw: 193 131 Batteria: 12.40 mAh: 0 A: 0.10 RC-Roll: 1500 RC-Pitch: 1500 RC-Throttle: 885 RC-Yaw: 1500 Att-Roll: -0.30 Att-Pitch: -1.40 Att-Yaw: 193 131 ...

and so on.

Can you tell me what is wrong with the above code? Please reply. Greetings!

Hey, I am trying something siliar, I am trying to get MPS telemetry data from a Naze32 to an Arduino Uno. I have read through your code and I just cannot wrap my head around it. I am trying to use D0 and D1 for Rx and Tx without softserial as I don't really know what is going on with that. I just want to be able to sent requests for data to teh flight controller using MSP and save the data to an SD card but id just be happy for it in my serial monitor right now. Does anyone have any idea?

virtualfish commented 5 years ago

I did it with software serial but it will work with the hardware serial too. The only thing is that you need two serial ports: one for communicating with the FC and another to monitor/debug so you will need to use two more pins and a software serial library. I cannot add comments to the code because the edit button does not work for me at this moment (I know I should have done it in the first place). What exactly you are not beeing able to do right now? This library definitely works! Can you post your code and output?

tfmo18 commented 5 years ago

So what I have right no is RX and TX on the arduino to the UART2 TX and RX on the FC. heres the code I stole and edited, #include "MSP.h" MSP msp;

void setup() {

Serial.begin(115200); msp.begin(Serial); }

void loop() { msp_rc_t rc; msp_attitude_t attitude; msp_analog_t analog;

if (msp.request(MSP_ANALOG, &analog, sizeof(analog))) { uint8_t vbat = analog.vbat; // 0...255 uint16_t mAhDrawn = analog.mAhDrawn; // milliamp hours drawn from battery uint16_t rssi = analog.rssi; // 0..1023 int16_t amperage = analog.amperage; // send amperage in 0.01 A steps, range is -320A to 320A
Serial.print("Batteria: " + String(vbat/10.0)); Serial.print(" mAh: " + String(mAhDrawn)); //mySerial.print(" RSSI: " + String(rssi)); Serial.println(" A: " + String(amperage/100.0)); }

if (msp.request(MSP_RC, &rc, sizeof(rc))) { uint16_t roll = rc.channelValue[0]; uint16_t pitch = rc.channelValue[1]; uint16_t yaw = rc.channelValue[2]; uint16_t throttle = rc.channelValue[3]; Serial.print("RC-Roll: " + String(roll)); Serial.print(" RC-Pitch: " + String(pitch)); Serial.print(" RC-Throttle: " + String(throttle)); Serial.println(" RC-Yaw: " + String(yaw)); }

if (msp.request(MSP_ATTITUDE, &attitude, sizeof(attitude))) { int16_t roll = attitude.roll; int16_t pitch = attitude.pitch; uint16_t yaw = attitude.yaw; Serial.print("Att-Roll: " + String(roll/10.0)); Serial.print(" Att-Pitch: " + String(pitch/10.0)); Serial.println(" Att-Yaw: " + String(yaw)); }

}`

and the output I am getting from that is

$M<nn$M<ii$M11 and that repeats.

I do have the FC and Arduino plugged in s I could understand if the error is becuse the usb is trying to use the RX and TX serial but even with soft-serial I can't seem to get anything at all.

virtualfish commented 5 years ago

You cannot use the same port for monitoring and for MSP $M<nn$M<ii$M11 <--- This MSP message should be sent to the FC not to the monitor The Arduino should be connected to both the PC (monitor) and the FC (MSP) but with two separate ports.

tfmo18 commented 5 years ago

Thank you I have it working now, is there a way to have it set up for a more continuous output? At the moment it seems to output on my serial very now and again? `#include

include "MSP.h"

SoftwareSerial mspSerial(10, 11); //RX TX MSP msp;

void setup() {

Serial.begin(115200); mspSerial.begin(115200); msp.begin(mspSerial); }

void loop() { msp_rc_t rc; msp_attitude_t attitude; msp_analog_t analog;

if (msp.request(MSP_ANALOG, &analog, sizeof(analog))) { uint8_t vbat = analog.vbat; // 0...255 uint16_t mAhDrawn = analog.mAhDrawn; // milliamp hours drawn from battery uint16_t rssi = analog.rssi; // 0..1023 int16_t amperage = analog.amperage; // send amperage in 0.01 A steps, range is -320A to 320A
Serial.print("Batteria: " + String(vbat/10.0)); Serial.print(" mAh: " + String(mAhDrawn)); //mySerial.print(" RSSI: " + String(rssi)); Serial.println(" A: " + String(amperage/100.0)); }

if (msp.request(MSP_RC, &rc, sizeof(rc))) { uint16_t roll = rc.channelValue[0]; uint16_t pitch = rc.channelValue[1]; uint16_t yaw = rc.channelValue[2]; uint16_t throttle = rc.channelValue[3]; Serial.print("RC-Roll: " + String(roll)); Serial.print(" RC-Pitch: " + String(pitch)); Serial.print(" RC-Throttle: " + String(throttle)); Serial.println(" RC-Yaw: " + String(yaw)); }

if (msp.request(MSP_ATTITUDE, &attitude, sizeof(attitude))) { int16_t roll = attitude.roll; int16_t pitch = attitude.pitch; uint16_t yaw = attitude.yaw; Serial.print("Att-Roll: " + String(roll/10.0)); Serial.print(" Att-Pitch: " + String(pitch/10.0)); Serial.println(" Att-Yaw: " + String(yaw)); } }` I am looking for a lot of data from the MSP, enough to have an effective blackbox.

tfmo18 commented 5 years ago

So I just changed the baud rate and that seemed to have sped thing up, how do I get the sensor readings into usable units? I am now using this code:



#include "MSP.h"
  SoftwareSerial mspSerial(10, 11); //RX TX
MSP msp;

void setup()
{

  Serial.begin(19200);
  mspSerial.begin(19200);
  msp.begin(mspSerial);
}

void loop()
{

  msp_rc_t rc;
  msp_attitude_t attitude;
  msp_raw_imu_t imu; 
  msp_altitude_t altitude;

  if (msp.request(MSP_RC, &rc, sizeof(rc))) {
    uint16_t roll     = rc.channelValue[0];
    uint16_t pitch    = rc.channelValue[1];
    uint16_t yaw      = rc.channelValue[2];
    uint16_t throttle = rc.channelValue[3];
    Serial.println("RC-Roll: " + String(roll));
    Serial.println(" RC-Pitch: " + String(pitch));
    Serial.println(" RC-Throttle: " + String(throttle));
    Serial.println(" RC-Yaw: " + String(yaw));
  }

  if (msp.request(MSP_ATTITUDE, &attitude, sizeof(attitude))) {
    int16_t roll     = attitude.roll;
    int16_t pitch    = attitude.pitch;
    uint16_t yaw      = attitude.yaw;
    Serial.println("Att-Roll: " + String(roll/10.0));
   Serial.println(" Att-Pitch: " + String(pitch/10.0));
   Serial.println(" Att-Yaw: " + String(yaw));
  }
  if (msp.request(MSP_RAW_IMU, &imu, sizeof(imu))) {
    uint16_t acc_x     = imu.acc[0];
    uint16_t acc_y     = imu.acc[1];
    uint16_t acc_z     = imu.acc[2];
    uint16_t gyro_x    = imu.gyro[0];
    uint16_t gyro_y    = imu.gyro[1];
    uint16_t gyro_z    = imu.gyro[2];
    uint16_t mag_x     = imu.mag[0];
    uint16_t mag_y     = imu.mag[1];
    uint16_t mag_z     = imu.mag[2];
  Serial.println("Accelerometer[x,y,z]: " + String(acc_x/448)+ ","+ String(acc_y/448) +","+ String(acc_z/448));
  Serial.println("Gyroscope[x,y,z]: " + String(gyro_x/2000)+ ","+ String(gyro_y/2000) +","+ String(gyro_z/2000));
  Serial.println("Magnetometer[x,y,z]: " + String(mag_x)+ ","+ String(mag_y) +","+ String(mag_z));
  }
  if (msp.request(MSP_ALTITUDE, &altitude, sizeof(altitude))) {
    int32_t alt_est  = altitude.estimatedActualPosition;  // cm
    int16_t vel_est  = altitude.estimatedActualVelocity;  // cm/s
    int32_t bara_alt = altitude.baroLatestAltitude;
    Serial.println("Estimated altitude: " + String(alt_est));
    Serial.println("Estimated Velocity: " + String(vel_est));
    Serial.println("Barometer altitude: " + String(bara_alt));
  }

} ```
When not moving the output is like this `Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
Accelerometer[x,y,z]: 0,146,1
Gyroscope[x,y,z]: 0,0,32
Magnetometer[x,y,z]: 0,0,0
Estimated altitude: 109
Estimated Velocity: 0
Barometer altitude: 0
RC-Roll: 1500
 RC-Pitch: 1500
 RC-Throttle: 885
 RC-Yaw: 1500
Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
Accelerometer[x,y,z]: 0,146,1
Gyroscope[x,y,z]: 0,32,32
Magnetometer[x,y,z]: 0,0,0
Estimated altitude: 106
Estimated Velocity: 0
Barometer altitude: 0
RC-Roll: 1500
 RC-Pitch: 1500
 RC-Throttle: 885
 RC-Yaw: 1500
Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
Accelerometer[x,y,z]: 0,146,1
Gyroscope[x,y,z]: 0,32,0
Magnetometer[x,y,z]: 0,0,0
Estimated altitude: 104
Estimated Velocity: 0
Barometer altitude: 0
RC-Roll: 1500
 RC-Pitch: 1500
 RC-Throttle: 885
 RC-Yaw: 1500
Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
Accelerometer[x,y,z]: 0,146,1
Gyroscope[x,y,z]: 32,32,32
Magnetometer[x,y,z]: 0,0,0
Estimated altitude: 103
Estimated Velocity: 0
Barometer altitude: 0
RC-Roll: 1500
 RC-Pitch: 1500
 RC-Throttle: 885
 RC-Yaw: 1500
Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
Accelerometer[x,y,z]: 0,146,1
Gyroscope[x,y,z]: 0,32,0
Magnetometer[x,y,z]: 0,0,0
Estimated altitude: 102
Estimated Velocity: 0
Barometer altitude: 0
RC-Roll: 1500
 RC-Pitch: 1500
 RC-Throttle: 885
 RC-Yaw: 1500
Att-Roll: -0.40
 Att-Pitch: -0.60
 Att-Yaw: 175
`
virtualfish commented 5 years ago

I am glad to hear that you sorted the communication out. The sensor variable like acc_x, acc_y, mag_x represent the sensor's output value and I ignore what their scale is and how the calibration settings are taken into account. I use roll pitch and yaw instead because it gives me the drone estimated position calculated durectly by the FC. (In the average of 360 degrees) Have a look at the table at this page: https://github.com/iNavFlight/inav/wiki/INAV-blackbox-variables it tells you the range for all inav variable (almost). Let us know!

apichaicoding commented 4 years ago

I would like to know if MSP is able to extract data from the Betaflight between the Controllor F4 G2 files and the Arduino Uno

Thank you