Go Down

Topic: Problem with transmitting IMU/GPS/Ultrasonic data over Nrf24L01 (Read 5971 times) previous topic - next topic

Cyric

HI there.
I have a problem with trying to transmit data from sensors from my bot using a mega with a NRF24L01 (long range 1,000m ver) to my base station using an UNO with same NRF24.
I "think" it has to do with sending various types of data at once like ints floats strings?
Can some one with experience in sending GPS or other like sensor data kind of guide me in this?
The TX sends some sort of data but it's all mucked up on the RX I do not know if it's getting messed up before (when being stuffed into the array for transmission) or after ti's being sent.
Here is my (TX) Code
Code: [Select]


void NrfTrans(){
 //****************************Info being Sent**********************
  // GPS NMEA data (3 vals)
 // IMU Roll Pitch Yaw (3 vals)
 //**************put values in array?**************
 byte vals[6];
 //**********Send IMU Roll Pitch Yaw values**********
 vals[0] =ToDeg(roll);   //example   + or - 134.987
 vals[1] =ToDeg(pitch); //example + or - 134.987
 vals[2] =ToDeg(yaw); // example  + or - 134.987
 vals[3] =flat;             //example 40.111111111
 vals[4] =flon;          //example -40.111111111
 vals[5] =Tgps.satellites(); //example 8
 //**************************************************
 //**************finish putting values in array?**************
 //**************Start Transmit package**************
 Mirf.setTADDR((byte *)"base1"); // set name of Reciever
 Mirf.send(vals); // data to send
 Serial.println(" Sent");
 while(Mirf.isSending()){
 }
 delay(10);
}

Here is my base station code (RX)

Code: [Select]

#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>
#include <SPI.h>
//-+-+-+>>>> NRF24 Incoming data holders<<<<<<-+-+-+
float val0; // IMU Roll  
float val1; // IMU Pitch
float val2; // IMU Yaw  
float val3; // Latitude
float val4; // Longitude
int val5; // # of Satalites
//*********************************************
void setup(){
 Serial.begin(57600);
 //**************Start Transiever (NRF24L01) config**************
 Serial.println("...Radio Booting..."); // print somthing once to Serial to know your up
 Mirf.cePin = 8;
 Mirf.csnPin = 9;
 Mirf.spi = &MirfHardwareSpi;
 Mirf.init();
 Mirf.setRADDR((byte *)"base1");
 Mirf.payload = 16 * sizeof(byte);
 Mirf.config();
 Serial.println("...Radio UP..."); // print somthing once to Serial to know your up
 //**************End Transiever (NRF24L01) config**************
}
void loop(){
 //-+-+-+>>>>Start data collection from transciever<<<<<<-+-+-+
 byte data[Mirf.payload];
 if(Mirf.dataReady()){
   do{
     Mirf.getData(data);
     //*********** Start array to collect pot/sensor data *********
     val0 = data[0]; //IMU Roll
     val1 = data[1]; //IMU Pitch
     val2 = data[2]; //IMU Yaw  
     val3 = data[3]; //IMU Latitude        
     val4 = data[4]; //IMU Longitude  
     val5 = data[5]; //IMU # of Satalites  
     //*********** End array to collect pot/sensor data *********    
     //**********Start Loop to print array to Serial Monitor
     /*
     int i;
      for (i = 0; i < 16; i = i + 1) {
      Serial.println(data[i], DEC);
      }          
      //*/

     //**********End Loop to print array to Serial Monitor        
     delay(10);
   }
   while(!Mirf.rxFifoEmpty());
 }
 //++++++++ END data collection from transciever++++++++++++


 Serial.print("!");
 Serial.print("ANG:");
 Serial.print(val0);
 Serial.print(",");
 Serial.print(val1);
 Serial.print(",");
 Serial.print(val2);
 Serial.println();
 Serial.print("Lat: ");
 Serial.print(val3);
 Serial.print(" Long: ");
 Serial.print(val4);
 Serial.print(" SAT: ");
 Serial.print(val5);
 Serial.println();

} // end of program


PeterH

You need to post ALL of your code for us to have any real chance of seeing the problem, but I suspect the problem may be that you're trying to store float values in bytes.
I only provide help via the forum - please do not contact me for private consultancy.

Cyric

#2
Jan 25, 2013, 10:54 pm Last Edit: Jan 26, 2013, 02:01 am by Cyric Reason: 1
tried to post the full code but the forum spit it back saying it was over the max 9500 chars. here is the TX so ill have to split it in 2 or more posts
Part_01
Code: [Select]

#include <NewPing.h>
#include <Arduino.h>
#include <Wire.h>
#include <stdio.h>
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>
#include <SPI.h>
#include <TinyGPS.h>
//-+-+-+>>>> START Ultrasonic Sensor section<<<<<<-+-+-+
#define TRIGGER_PIN  23  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     22  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
//-+-+-+>>>> END Ultrasonic Sensor section<<<<<<-+-+-+
//-+-+-+>>>> START MotorDriver Vars section<<<<<<-+-+-+
#define Mspeed0 0
#define Mspeed1 100
#define Mspeed2 150
#define runs1 2
#define runs2 3
#define mDelay1 100
#define mDelay2 150
//-+-+-+>>>> END MotorDriver Vars section<<<<<<-+-+-+
//-+-+-+>>>> START GPS Vars section<<<<<<-+-+-+
#define WPT_IN_RANGE_M 1
//-+-+-+>>>> END GPS Vars section<<<<<<-+-+-+
//-+-+-+>>>> SRTART POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
// LSM303 accelerometer: 8 g sensitivity
// 3.8 mg/digit; 1 g = 256
#define GRAVITY 256  //this equivalent to 1G in the raw data coming from the accelerometer
#define ToRad(x) ((x)*0.01745329252)  // *pi/180
#define ToDeg(x) ((x)*57.2957795131)  // *180/pi
// L3G4200D gyro: 2000 dps full scale
// 70 mdps/digit; 1 dps = 0.07
#define Gyro_Gain_X 0.07 //X axis Gyro gain
#define Gyro_Gain_Y 0.07 //Y axis Gyro gain
#define Gyro_Gain_Z 0.07 //Z axis Gyro gain
#define Gyro_Scaled_X(x) ((x)*ToRad(Gyro_Gain_X)) //Return the scaled ADC raw data of the gyro in radians for second
#define Gyro_Scaled_Y(x) ((x)*ToRad(Gyro_Gain_Y)) //Return the scaled ADC raw data of the gyro in radians for second
#define Gyro_Scaled_Z(x) ((x)*ToRad(Gyro_Gain_Z)) //Return the scaled ADC raw data of the gyro in radians for second
// LSM303 magnetometer calibration constants; use the Calibrate example from
// the Pololu LSM303 library to find the right values for your board
#define M_X_MIN -602
#define M_Y_MIN -668
#define M_Z_MIN -592
#define M_X_MAX 391
#define M_Y_MAX 422
#define M_Z_MAX 524
#define Kp_ROLLPITCH 0.02
#define Ki_ROLLPITCH 0.00002
#define Kp_YAW 1.2
#define Ki_YAW 0.00002
//OUTPUTMODE=1 will print the corrected data,
//OUTPUTMODE=0 will print uncorrected data of the gyros (with drift)
#define OUTPUTMODE 1
//#define PRINT_DCM 0     //Will print the whole direction cosine matrix
#define PRINT_ANALOGS 0 //Will print the analog raw data
#define PRINT_EULER 1   //Will print the Euler angles Roll, Pitch and Yaw
#define STATUS_LED 13
//-+-+-+>>>> END POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
//-+-+-+>>>> START MotorDriver Vars section<<<<<<-+-+-+
int DIR_A = 12;    //L298 DIR A  Digital High/Low = left/right
int PWM_A = 3;     //L298 PWM A Analog
int ENA_A = 9;     //L298 Enable A Digital Hight/low on/off
int DIR_B = 13;    //L298 DIR A  Digital High/Low = left/right
int PWM_B = 11;    //L298 PWM A Analog
int ENA_B = 8;     //L298 Enable A Digital Hight/low on/off
int oTime = 0;
//-+-+-+>>>> END MotorDriver Vars section<<<<<<-+-+-+
//-+-+-+>>>> SRTART POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
int SENSOR_SIGN[9] = {
 1,1,1,-1,-1,-1,1,1,1}; //Correct directions x,y,z - gyro, accelerometer, magnetometer
float G_Dt=0.02;    // Integration time (DCM algorithm)  We will run the integration loop at 50Hz if possible
long timer=0;   //general purpuse timer
long timer_old;
long timer24=0; //Second timer used to print values
int AN[6]; //array that stores the gyro and accelerometer data
int AN_OFFSET[6]={
 0,0,0,0,0,0}; //Array that stores the Offset of the sensors
int gyro_x;
int gyro_y;
int gyro_z;
int accel_x;
int accel_y;
int accel_z;
int magnetom_x;
int magnetom_y;
int magnetom_z;
float c_magnetom_x;
float c_magnetom_y;
float c_magnetom_z;
float MAG_Heading;
float Accel_Vector[3]= {
 0,0,0}; //Store the acceleration in a vector
float Gyro_Vector[3]= {
 0,0,0};//Store the gyros turn rate in a vector
float Omega_Vector[3]= {
 0,0,0}; //Corrected Gyro_Vector data
float Omega_P[3]= {
 0,0,0};//Omega Proportional correction
float Omega_I[3]= {
 0,0,0};//Omega Integrator
float Omega[3]= {
 0,0,0};
// Euler angles
float roll;
float pitch;
float yaw;
float errorRollPitch[3]= {
 0,0,0};
float errorYaw[3]= {
 0,0,0};
unsigned int counter=0;
byte gyro_sat=0;
float DCM_Matrix[3][3]= {
 {
   1,0,0                  }
 ,{
   0,1,0                  }
 ,{
   0,0,1                  }
};
float Update_Matrix[3][3]={
 {
   0,1,2                }
 ,{
   3,4,5                }
 ,{
   6,7,8                }
}; //Gyros here
float Temporary_Matrix[3][3]={
 {
   0,0,0                  }
 ,{
   0,0,0                  }
 ,{
   0,0,0                  }
};
//-+-+-+>>>> END POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
//-+-+-+>>>> START Ultrasonic Sensor section<<<<<<-+-+-+
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance, centerDistance; //distances on either side
//-+-+-+>>>> END Ultrasonic Sensor section<<<<<<-+-+-+
//-+-+-+>>>> Start Tac sensor contact section<<<<<<-+-+-+
int leftWiskerPin = 31;
int rightWiskerPin = 30;
int oldLeftWiskerValue;
int oldRightWiskerValue;
int numOfLeftWiskerhits = 0;
int numOfRightWiskerhits = 0;
int leftWiskerValue;
int rightWiskerValue;
//-+-+-+>>>> END Tac sensor contact section<<<<<<-+-+-+
//-+-+-+>>>> Start US PING averaging section<<<<<<-+-+-+
//------------------Avrageing-----------------------------------
const int numReadings = 5;
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
//------------------Avrageing-----------------------------------
//-+-+-+>>>> END US PING averaging section<<<<<<-+-+-+
//-+-+-+>>>> START GPS INIT section<<<<<<-+-+-+
TinyGPS Tgps;
float flat, flon;
//-+-+-+>>>> END GPS INIT section<<<<<<-+-+-+
//-+-+-+>>>> Start VT100 INIT section<<<<<<-+-+-+
//-+-+-+>>>> END VT100 INIT section<<<<<<-+-+-+

void setup()
{
 Serial.begin(57600);
 Serial2.begin(57600); //GPS INPUT (LocoSYS LS20031)
 //**************Start Transiever (NRF24L01) config**************
 Serial.println("Radio Booting ... "); // Print some stuff to serial
 Mirf.cePin = 48;
 Mirf.csnPin = 49;
 Mirf.spi = &MirfHardwareSpi;
 Mirf.init();
 Mirf.setRADDR((byte *)"robot");
 Mirf.payload = 16 * sizeof(byte);
 Mirf.config();
 Serial.println("Radio UP ... "); // Print some stuff to serial
 //**************End Transiever (NRF24L01) config**************
 //-+-+-+>>>> Start Tac sensor contact section<<<<<<-+-+-+
 pinMode(leftWiskerPin, INPUT);
 pinMode(rightWiskerPin, INPUT);
 digitalWrite(leftWiskerPin, HIGH);
 digitalWrite(rightWiskerPin, HIGH);  
 //-+-+-+>>>> END Tac sensor contact section<<<<<<-+-+-+
 //-+-+-+>>>> START MotorDriver Vars section<<<<<<-+-+-+
 pinMode(DIR_A, OUTPUT);  
 pinMode(PWM_A, OUTPUT);
 pinMode(ENA_A, OUTPUT);  
 pinMode(DIR_B, OUTPUT);  
 pinMode(PWM_B, OUTPUT);
 pinMode(ENA_B, OUTPUT);
 //-+-+-+>>>> START MotorDriver Vars section<<<<<<-+-+-+
 //-+-+-+>>>> Start US PING averaging section<<<<<<-+-+-+
 for (int thisReading = 0; thisReading < numReadings; thisReading++)
   readings[thisReading] = 0;        
 //-+-+-+>>>> END US PING averaging section<<<<<<-+-+-+
 //-+-+-+>>>> Start VT100 INIT section<<<<<<-+-+-+  
 Serial.print(BYB);
 Serial.println(CLR);  
 //-+-+-+>>>> END VT100 INIT section<<<<<<-+-+-+
 //-+-+-+>>>> START POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
 Serial.println("IMU INIT ... "); // Print some stuff to serial
 I2C_Init();
 delay(1500);
 Accel_Init();
 Compass_Init();
 Gyro_Init();
 delay(20);
 for(int i=0;i<32;i++)    // We take some readings...
 {
   Read_Gyro();
   Read_Accel();
   for(int y=0; y<6; y++)   // Cumulate values
     AN_OFFSET[y] += AN[y];
   delay(20);
 }
 for(int y=0; y<6; y++)
   AN_OFFSET[y] = AN_OFFSET[y]/32;
 AN_OFFSET[5]-=GRAVITY*SENSOR_SIGN[5];
 for(int y=0; y<6; y++)
   delay(2000);  
 timer=millis();
 delay(20);
 counter=0;
 Serial.println("IMU Stream active ... "); // Print some stuff to serial
 //-+-+-+>>>> END POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
}


Cyric

Part_02
Code: [Select]


void loop()
{
  unsigned  int distanceFwd = averagePing();
  if (distanceFwd > dangerThresh){
    MoveForward(Mspeed1,runs2,mDelay1);
    WiskerCheck(); 
  }
  else{
    PingScan(distanceFwd);
    WiskerCheck(); 
  }
 
  TgpsOut();
  MinImu9();
  NrfTrans();
  WiskerCheck(); 
}
//-+-+-+>>>> Start Nrf24L01 Transmitter Section<<<<<<-+-+-+
void NrfTrans(){
  //****************************Info being Sent**********************
  // Ultrasonic Vals (1 val)
  // GPS NMEA data (? vals)
  // IMU Roll Pitch Yaw (3 vals)
  // Wisker hits (2vals)
  //**************put values in array?**************
  byte vals[6];
  //**********Send IMU Roll Pitch Yaw values**********
  vals[0] =ToDeg(roll);
  vals[1] =ToDeg(pitch); 
  vals[2] =ToDeg(yaw);
  vals[3] =flat;
  vals[4] =flon;
  vals[5] =Tgps.satellites();
  //**************************************************
  //**************finish puting values in array?**************
  //**************Start Transmit package**************
  Mirf.setTADDR((byte *)"base1"); // set name of Reciever
  Mirf.send(vals); // data to send
  Serial.println(" Sent");
  while(Mirf.isSending()){
  }
  delay(10);
}
//-+-+-+>>>> End Nrf24L01 Transmitter Section<<<<<<-+-+-+
float TgpsOut()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;
  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 100;)
  {
    while (Serial2.available())
    {
      char c = Serial2.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (Tgps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    //    float flat, flon;
    unsigned long age;
    Tgps.f_get_position(&flat, &flon, &age);
    /*
    Serial.print("LAT=");
     Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
     Serial.print(" LON=");
     Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
     Serial.print(" SAT=");
     Serial.print(Tgps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : Tgps.satellites());
     Serial.print(" PREC=");
     Serial.print(Tgps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : Tgps.hdop());
     */
    return flat,flon;     
  }
  /*
  Tgps.stats(&chars, &sentences, &failed);
   Serial.print(" CHARS=");
   Serial.print(chars);
   Serial.print(" SENTENCES=");
   Serial.print(sentences);
   Serial.print(" CSUM ERR=");
   Serial.println(failed);
   */
}
//-+-+-+>>>> START Sensor readings section<<<<<<-+-+-+
unsigned int  ping(){
  WiskerCheck();
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  return uS / US_ROUNDTRIP_CM;
}
unsigned int averagePing(){
  total= total - readings[index]; // subtract the last reading:
  readings[index] = ping();   // read from the sensor: 
  total= total + readings[index];   // add the reading to the total:
  index = index + 1;  // advance to the next position in the array: 
  if (index >= numReadings)  // if we're at the end of the array...
    index = 0;   // ...wrap around to the beginning:                           
  average = total / numReadings;   // calculate the average:
  delay(1);        // delay in between reads for stability           
  return average;   // send it as ASCII digits
}
unsigned int PingScan(unsigned int Fwddist){
  if (Fwddist <= dangerThresh){
    centerDistance  = averagePing();
    if (centerDistance <= dangerThresh){
      MoveBackward(Mspeed2,runs2,mDelay2);
      MoveLeft(Mspeed1,runs1,mDelay1);
      WiskerCheck();
    }
    else{
      return 0;
    }

  }

void WiskerCheck(){
  int Tcount = 5;
  oldLeftWiskerValue = leftWiskerValue;
  oldRightWiskerValue = rightWiskerValue;
  leftWiskerValue = digitalRead(leftWiskerPin);
  rightWiskerValue = digitalRead(rightWiskerPin); 
  if((leftWiskerValue == LOW) && (oldLeftWiskerValue == HIGH))
  {
    MoveStop(Mspeed0,runs1,mDelay1);
    for (int LwiskT =0; LwiskT < Tcount; LwiskT++){
      MoveBackward(Mspeed2,runs2,mDelay2);
      MoveRight(Mspeed2,runs2,mDelay2);
    }
    return;
  }
  if((rightWiskerValue == LOW) && (oldRightWiskerValue == HIGH))
  {
    MoveStop(Mspeed0,runs1,mDelay1);
    for (int LwiskT =0; LwiskT < Tcount; LwiskT++){
      MoveBackward(Mspeed2,runs2,mDelay2);
      MoveLeft(Mspeed2,runs2,mDelay2);
    }
    return;
  }
  else{
    //Serial.println("=>WiskerCheck: else triggered<=");
    return;
  }
  return;
}
//-+-+-+>>>>START POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
void MinImu9() //PoloLU MINIMU -9DOF
{

  if((millis()-timer)>=20)  // Main loop runs at 50Hz
  {
    counter++;
    timer_old = timer;
    timer=millis();
    if (timer>timer_old)
      G_Dt = (timer-timer_old)/1000.0;    // Real time of loop run. We use this on the DCM algorithm (gyro integration time)
    else
      G_Dt = 0;
    // *** DCM algorithm
    // Data adquisition
    Read_Gyro();   // This read gyro data
    Read_Accel();     // Read I2C accelerometer
    if (counter > 5)  // Read compass data at 10Hz... (5 loop runs)
    {
      counter=0;
      Read_Compass();    // Read I2C magnetometer
      Compass_Heading(); // Calculate magnetic heading 
    }
    // Calculations...
    Matrix_update();
    Normalize();
    Drift_correction();
    Euler_angles();
    // ***
    //   VTprintdata();
    // printdata();
  }
}
//-+-+-+>>>> END POLOLU MINIMU - 9DOF Sensor section<<<<<<-+-+-+
//-+-+-+>>>> END Sensor readings section<<<<<<-+-+-+

//-+-+-+>>>> Motor Driver section<<<<<<-+-+-+
void MoveLeft(int SPD, int mTime, int mDelay)
{
  //int oTime = 0;
  while (oTime < mTime){
    digitalWrite(ENA_A, LOW);
    digitalWrite(DIR_A, HIGH);
    analogWrite(PWM_A, SPD);
    digitalWrite(ENA_B, LOW);
    digitalWrite(DIR_B, LOW);
    analogWrite(PWM_B, SPD);
    delay(mDelay1);
    oTime++;
  }
}

void MoveRight(int SPD, int mTime, int mDelay)
{
  //  int oTime = 0;
  while (oTime < mTime){
    digitalWrite(ENA_A, LOW);
    digitalWrite(DIR_A, LOW);
    analogWrite(PWM_A, SPD);
    digitalWrite(ENA_B, LOW);
    digitalWrite(DIR_B, HIGH);
    analogWrite(PWM_B, SPD);
    delay(mDelay);
    oTime++;
  }
}
void MoveForward(int SPD, int mTime,int mDelay)
{
  //  int oTime = 0;
  while (oTime < mTime){
    digitalWrite(ENA_A, LOW);
    digitalWrite(DIR_A, HIGH);
    analogWrite(PWM_A, SPD);
    digitalWrite(ENA_B, LOW);
    digitalWrite(DIR_B, HIGH);
    analogWrite(PWM_B, SPD); //move forward
    delay(mDelay);
    oTime++;
  }
}
void MoveBackward(int SPD, int mTime,int mDelay)
{
  //  int oTime = 0;
  while (oTime < mTime){
    digitalWrite(ENA_A, LOW);
    digitalWrite(DIR_A, LOW);
    analogWrite(PWM_A, SPD);
    digitalWrite(ENA_B, LOW);
    digitalWrite(DIR_B, LOW);
    analogWrite(PWM_B, SPD);
    delay(mDelay);
    oTime++;
  }
}
void MoveStop(int SPD, int mTime,int mDelay)
{
  //  int oTime = 0;
  while (oTime < mTime){
    digitalWrite(ENA_A, HIGH);
    digitalWrite(DIR_A, HIGH);
    analogWrite(PWM_A, SPD);
    digitalWrite(ENA_B, HIGH);
    digitalWrite(DIR_B, HIGH);
    analogWrite(PWM_B, SPD);
    delay(mDelay);
    oTime++;
  }
}
//-+-+-+>>>> Motor Driver section<<<<<<-+-+-+

PaulS

Code: [Select]
String OFF = "\033[0m";
String BOLD = "\033[1m";
String CLR = "\e[2J"; 
String CLRl = "\e[2K";
String BYB = "\e[1;33;40m";

What a waste.

Code: [Select]
#define ToRad(x) ((x)*0.01745329252)  // *pi/180
#define ToDeg(x) ((x)*57.2957795131)  // *180/pi
float flat, flon;

byte vals[6];
  //**********Send IMU Roll Pitch Yaw values**********
  vals[0] =ToDeg(roll);
  vals[1] =ToDeg(pitch); 
  vals[2] =ToDeg(yaw);
  vals[3] =flat;
  vals[4] =flon;

You don't have a clue about variable types, do you? You can't store floating point data in 8 bit, integer variables.

And, this is quite novel:
Code: [Select]
    return flat,flon;     
Completely wrong, but you get points for inventiveness.

Cyric

i use the ESC codes for VT100 term output, i took them out because i know most of you use the generic arduino ide serial monitor.
They now have been removed.
as for the return well i am still quite learning i just learned last week how to pass arguments to external functions so still need lots of work learning how to get them out.
i am still shopping in the noob section i think.
as for trying to stuff floats into byte array yea i know it would not work but it showed what i need to accomplish.
if i had a nickle for every float to byte, f to b array converter i have looked at in the past 4 days i would be able to buy a starbucks coffee.
i am thinking type casting is where i need to look? or i have seen some typedef union stuff.
so to answer your question NO i do not know much about var types and i am not that experienced with programing on any level.
but i keep plugging away at it and learning as i go.
so i will say sorry now for being bad at programming and if that is not welcome here let me know.
so any ideas on fixes for the return flat,flon and ANY help on the float to byte method would be fantastic.

michinyon

Well if you want to pass a bunch of different data types,  I suggest you define
a struct with your data  and then a union to an array of bytes.

Find a C textbook  and read the section about structs and unions.

And then read about how functions work.

And then read about data types.


Cyric

WOW thanks i got your post a couple min after to made and and just got it to work. here is what i did

TX side
Code: [Select]

union imur_t {
   byte  Uroll[4];
   float froll;
}imur;
   imur.froll = ToDeg(roll);
  byte vals[4];
  vals[0] = imur.Uroll[0];
  vals[1] = imur.Uroll[1]; 
  vals[2] = imur.Uroll[2];
  vals[3] = imur.Uroll[3];

then i push vals out like before in the Nrf function
and i did the reverse on the other side like this

RX side
Code: [Select]

union imur_t {
   byte  Uroll[4];
   float froll;
}imur;
    imur.Uroll[0] = data[0];
    imur.Uroll[1] = data[1];
    imur.Uroll[2] = data[2];
    imur.Uroll[3] = data[3];

and then printed it out and boom there it was. -0.03 or 1.37 etc what ever the roll on the IMU was it sent it across. WOOT!. yes i am excited cos that %100 my own work. took over  WELL over 100 tries the past few hours. it's now 1:33am here time for bedZ. now the big question is there better why than this because i have roll pitch yaw just on the imu and then i have the GPS sentences and the ultrasonic stuffs to do along with others. do i have to create... ( brain fart, cant i just make a function and send it transmit var in the type of a float and have it return the bytes and send them auto to the nrf?) like f2bconv(Sensor1()); and sen 1 being in form of a float be chopped and passed to Mirf.send? sorry it is real  late here and i am not "good" at this fresh in the morning much less now lol. ill translate this in the morning! :) ( i hope)

PaulS

The function to send an array of bytes can send the bytes from any memory location. Define a struct. Store the data in an instance of the struct. Call the function to send the data with the struct instance and the size of the struct.

That function does not want a struct? Lie to it. Tell it that the struct is really a collection of bytes, using a cast - (byte *). Use the sizeof() function to get the number of bytes to send.

Cyric

like this but with structs?
i did this last night before i went to bed.
TX
Code: [Select]

float Tflo2byte(float inflo){

  union flow2byte_t {
    byte  outbyte[4];
    float infloat;
  }
  flow2byte;
  flow2byte.infloat = inflo;
  byte output[4];
  output[0] = flow2byte.outbyte[0];
  output[1] = flow2byte.outbyte[1]; 
  output[2] = flow2byte.outbyte[2];
  output[3] = flow2byte.outbyte[3];

  Mirf.setTADDR((byte *)"base1"); // set name of Reciever
  Mirf.send(output); // data to send
  while(Mirf.isSending()){
  }
  delay(10);
}


Rx side in main loop
Code: [Select]

byte data[Mirf.payload];
  if(Mirf.dataReady()){
    do{
      Mirf.getData(data);
      byte2flo(data); // send to byte to float converter
      delay(10);
    }
    while(!Mirf.rxFifoEmpty());
  }

external to loop
Code: [Select]

void byte2flo(byte data[]){
  //*********** Start convertion from byte to float *********
  union byte2flo_t {
    byte  outbyte[4];
    float outfloat;
  }
  byte2flo;
  byte2flo.outbyte[0]= data[0];
  byte2flo.outbyte[1]= data[1]; 
  byte2flo.outbyte[2]= data[2];
  byte2flo.outbyte[3]= data[3];
  Serial.println(byte2flo.outfloat);
  //*********** END convertion from byte to float *********

}

works but this is the output
0.38
-1.28
-12.58
now i have to "collect" the data and store it so i can turn that into something along the lines !IMU:0.38,-1.28,-12.58: (!) start of line (:) end of line for external programs like processing or python.
point me in the general direction i need to do this? like some kind of scanning routine that watches the incoming data or something.
ill go check out structs now. thanks for the input PaulS and michinyon
i appreciate this a lot.

Cyric


The function to send an array of bytes can send the bytes from any memory location. Define a struct. Store the data in an instance of the struct. Call the function to send the data with the struct instance and the size of the struct.

That function does not want a struct? Lie to it. Tell it that the struct is really a collection of bytes, using a cast - (byte *). Use the sizeof() function to get the number of bytes to send.


this does not compile i know. just wanted to know if i am heading in the right direction
Code: [Select]

   typedef struct{
    float roll;
    float pitch;
    float yaw;
  }floatImu;
 
   floatImu inImu[2];
  inImu[0].roll  = ToDeg(roll);
  inImu[0].pitch = ToDeg(pitch);
  inImu[0].yaw   = ToDeg(yaw);
  inImu[1] = (floatImu){roll,pitch,yaw};
  outD = inImu[1];
 
  Mirf.setTADDR((byte *)"base1"); // set name of Reciever
  Mirf.send(outD); // data to send
  while(Mirf.isSending()){
  }
  delay(10);


PaulS

Quote
just wanted to know if i am heading in the right direction

You are not headed in the wrong direction.

It isn't clear why you have two instances of the struct, or what roll, pitch, and yaw are, or what outD is.

Cyric

eep! 2? my understanding of stucts must be way off then here is what i understood it to be
Code: [Select]

RPYtransmit(ToDeg(roll),ToDeg(pitch),ToDeg(yaw));

Code: [Select]

void RPYtransmit(float inRoll, float inPitch, float inYaw){ //recieve current vals for ToDeg(roll),ToDeg(pitch),ToDeg(yaw)

    typedef struct
    {
    float roll; // place for roll value here
    float pitch;// place for pitch value here
    float yaw;  // place for yaw value here
   }RPYT_type; // lable the struct

    RPYT_type imuArray[2]; // create an array to hold roll,pitch,yaw for transmission


  imuArray[0].roll  = inRoll; // give float roll in RPYT_type value from incoming function argument inRoll
  imuArray[0].pitch = inPitch;// give float pitch in RPYT_type value from incoming function argument inPitch
  imuArray[0].yaw   = inYaw;// give float yaw in RPYT_type value from incoming function argument inYaw
  imuArray[1] = (RPYT_type) {inRoll,inPitch,inYaw}; // combine inRoll,inPitch,inYaw from RPYT_type into imuArray position 2 (0 being first position in array)

  Mirf.setTADDR((byte *)"base1"); // set name of Receiver
  Mirf.send(imuArray[2]); // figure out how to access and transmit second array segment containing inRoll,inPitch,inYaw
  while(Mirf.isSending()){
  }
  delay(10);
}

PaulS

Code: [Select]
    RPYT_type imuArray[2]; // create an array to hold roll,pitch,yaw for transmission
This is creating an array of structs. The question is why? Why 2?

Each instance of the struct can hold roll, pitch, AND yaw. You do not heed three instances of the struct to hold the three values. And, you certainly don't need two instance for three values.

Cyric

ahh ok think im starting to see now

Code: [Select]

void RPYtransmit(float inRoll, float inPitch, float inYaw){ //recieve current vals for ToDeg(roll),ToDeg(pitch),ToDeg(yaw)

    typedef struct
    {
    float roll; // place roll value here
    float pitch;// place pitch value here
    float yaw;  // place yaw value here
   }RPYT_type; // lable the struct

  RPYT_type imuVal = {inRoll,inPitch,inYaw}; // give float roll in RPYT_type value from incoming function argumet inRoll
  Serial.println("");
    Serial.print(imuVal.roll);
  Serial.print(" , ");
    Serial.print(imuVal.pitch);
  Serial.print(" , ");
    Serial.print(imuVal.yaw);
  Serial.println("");
}

so how do i trick Mirf.send(); into thinking this is once piece of data?

Go Up