Example of reading and magnetometer sensor (HMC5883L)
Dependencies: MODSERIAL mbed-rtos mbed
Fork of ReadingMag_HMC5883L by
Revision 1:aea254b39529, committed 2016-05-24
- Comitter:
- Maor_T
- Date:
- Tue May 24 12:08:14 2016 +0000
- Parent:
- 0:6bc5f85ca6fa
- Commit message:
- amir
Changed in this revision
diff -r 6bc5f85ca6fa -r aea254b39529 HMC5883L.h --- a/HMC5883L.h Tue May 21 13:48:10 2013 +0000 +++ b/HMC5883L.h Tue May 24 12:08:14 2016 +0000 @@ -30,8 +30,9 @@ float getMx(); float getMy(); float getMz(); + void Write(char reg_address, char data); private: - void Write(char reg_address, char data); + char Read(char data); void MultiByteRead(char address, char* output, int size); I2C i2c;
diff -r 6bc5f85ca6fa -r aea254b39529 MODSERIAL.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Tue May 24 12:08:14 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
diff -r 6bc5f85ca6fa -r aea254b39529 main.cpp --- a/main.cpp Tue May 21 13:48:10 2013 +0000 +++ b/main.cpp Tue May 24 12:08:14 2016 +0000 @@ -1,69 +1,328 @@ #include "mbed.h" #include "HMC5883L.h" +#include <math.h> +#include "rtos.h" +#include <string> +#define SDA_ARM p28 //p9 +#define SCL_ARM p27 //p10 +#define SDA_BODY p9 //p28 +#define SCL_BODY p10 //p27 +#define PI 3.14159265 +#define SERVO_PIN p21 +#define MaxDegreeDeviation 2 // how many degrees to ignore near north / target +#define ARM_MOUNT_ANGLE -70 +#define BODY_MOUNT_ANGLE 0 //was -50 +#define CCW_MIN_SPEED 1540 //1550 +#define CCW_MAX_SPEED 1800 -#include <math.h> +#define CW_MIN_SPEED 1460 // 1450 +#define CW_MAX_SPEED 1200 + +//#define DEBUG_ARM_LOCK_TIMER +//#define DEBUG_SERVO_PWM +//#define DEBUG_GRAPH + +Serial pc(USBTX,USBRX); +int TargetAngle = 0; +float BODY_MOUNT_RAD_FIX = BODY_MOUNT_ANGLE / 180.0 * PI; +float Arm_RAD_FIX = (ARM_MOUNT_ANGLE/180.0*PI) - (TargetAngle/180.0 * PI); +float declinationAngle = 0.069; // fix by position (radian) - netanya is 0.069 (3.6 deg) +PwmOut Servo(SERVO_PIN); +bool moveFlag = false; + +Serial BT(p13, p14); +float degreeToNorthArm = 0,degreeToNorthBody=0; +int bodyLastDegree = 0; +float z,x,y;; +HMC5883L hmc_arm(SDA_ARM, SCL_ARM); +HMC5883L hmc_body(SDA_BODY, SCL_BODY); + +DigitalOut led2(LED2); + +Ticker BTtimer; +Ticker Arm_timer; +Timer ArmlockTimer; +Timer globalTimer; + +//char globalChar = ' '; +string globalString =" "; + +//prototypes: +void BTsendDegrees(float degree); +void BTsendInterval(); +void Arm_Ticker(); +void Read_Magnetic_arm(); +void Read_Magnetic_body(); +float GetDegreeToNorth(int sensor); + + + +float map(float x, float in_min, float in_max, float out_min, float out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} -#define SDA p9 -#define SCL p10 -#define PI 3.14159265 +void RotateClockWise(int moveSpeed) +{ + led2 = 1; + moveFlag = true; + int moveSpeedCalc = map(180-moveSpeed,MaxDegreeDeviation,180,CW_MAX_SPEED,CW_MIN_SPEED); + Servo.pulsewidth_us(moveSpeedCalc); + // Servo.pulsewidth(CW_MAX_SPEED); + // wait_ms(SERVO_WAIT_TRIGGERS); + //Servo.pulsewidth_us(1500); + + #ifdef DEBUG_SERVO_PWM + printf("CW Servo Heading Speed : %d\tActualPwm: %.6f\n",moveSpeed,moveSpeedCalc); + #endif + + #ifdef DEBUG_ARM_LOCK_TIMER + ArmlockTimer.start(); + #endif + + #ifdef DEBUG_GRAPH + printf("%d,%d,%d\n",globalTimer.read_ms(),moveSpeed,moveSpeedCalc); + #endif +} + + +void RotateCounterClockWise(int moveSpeed) +{ + led2 = 1; + moveFlag = true; + int moveSpeedCalc = map(abs(moveSpeed),MaxDegreeDeviation,180,CCW_MIN_SPEED,CCW_MAX_SPEED); + Servo.pulsewidth_us(moveSpeedCalc); + // Servo.pulsewidth(CCW_MAX_SPEED); + // wait_ms(SERVO_WAIT_TRIGGERS); + //Servo.pulsewidth_us(1500); + #ifdef DEBUG_SERVO_PWM + printf("CCW Servo Heading Speed : %d\tActualPwm: %.6f\n",moveSpeed,moveSpeedCalc); + #endif + #ifdef DEBUG_ARM_LOCK_TIMER + ArmlockTimer.start(); + #endif + #ifdef DEBUG_GRAPH + printf("%d,%d,%d\n",globalTimer.read_ms(),moveSpeed,moveSpeedCalc); + #endif +} + +void StopServo() +{ + led2 = 0; + //myServo.writeMicroseconds(1500); + Servo.pulsewidth(0.0015); // pulse width 1500ms - servo stop + #ifdef DEBUG_ARM_LOCK_TIMER + if(moveFlag) + { + ArmlockTimer.stop(); + // printf("Arm locking time : %d ms\n",ArmlockTimer.read_ms()); // - Print the incoming command + ArmlockTimer.reset(); + moveFlag = false; + } + #endif +} + + +void DataReceived_ISR(){ + char globalChar = LPC_UART1->RBR; + globalString += globalChar; +} + +int getCommandValue(string cmd){ + string cmdValue; + std::size_t sharpPosition = cmd.find("#"); + cmdValue = cmd.substr(sharpPosition+1); + // printf("cmdvalue %s\n",cmdValue); // - Print the incoming command + return atoi(cmdValue.c_str()); +} -int main() -{ - float x, y, z, heading; - /* - float m_x, m_y, m_z; - */ - printf("Inicializing...\r\n"); - HMC5883L hmc5883l(SDA, SCL); - //HMC5883L *hmc5883l = new HMC5883L(SDA, SCL); - printf("OK...\r\n"); - /* - for (int i = 0 ; i < 100 ; i++) +void BTCommands (string cmd) +{ + + //printf("Input = %s\n",globalString); // - Print the incoming command + + if (cmd.find("Target")!= string::npos) + { + TargetAngle = getCommandValue(cmd); + Arm_RAD_FIX = Arm_RAD_FIX = (ARM_MOUNT_ANGLE/180.0*PI) - (TargetAngle/180.0 * PI); + // printf("New Target Angle set to: %d\n",TargetAngle); + } + +} + +void thread1(void const *args) //arm thread +{ + while(true) { + degreeToNorthArm = GetDegreeToNorth(2); // 2 is arm sensor + + if(degreeToNorthArm > MaxDegreeDeviation) + RotateClockWise(degreeToNorthArm); + else if(degreeToNorthArm < -MaxDegreeDeviation) + RotateCounterClockWise(degreeToNorthArm); + + else + StopServo(); + + Thread::wait(10); + } +} + +void thread2(void const *args) //body thread +{ + while(true) { + degreeToNorthBody = GetDegreeToNorth(1); + if(abs(bodyLastDegree - degreeToNorthBody) > 2) + { + // printf("degrees: %f\n ",degreeToNorthBody); + BTsendDegrees(degreeToNorthBody); + bodyLastDegree = degreeToNorthBody; + Thread::wait(800); + } + else + Thread::wait(800); + } +} + + + +void thread3(void const *args) +{ + while(true) { + if(globalString.length() > 0 ) + { + BTCommands(globalString); + globalString = ""; + } + + Thread::wait(100); + } +} + +void BTsendDegrees(float degree) +{ + BT.printf("#%f~",degree); +} + +void BTsendInterval() +{ + degreeToNorthBody = GetDegreeToNorth(1); + BTsendDegrees(degreeToNorthBody); + // Arm_timer.attach(Arm_Ticker, 0.0001); // activate arm sensor read frequency +} + +void Read_Magnetic_arm() +{ + x = hmc_arm.getMx(); + y = hmc_arm.getMy(); + z = hmc_arm.getMz(); +} + +void Read_Magnetic_body() +{ + x = hmc_body.getMx(); + y = hmc_body.getMy(); + z = hmc_body.getMz(); +} + +float GetDegreeToNorth(int sensor) +{ + float heading; + + + switch(sensor) { - x += hmc5883l.getMx()/100; - y += hmc5883l.getMy()/100; - z += hmc5883l.getMz()/100; - wait_ms(100); + case 1: // body + Read_Magnetic_body(); + + heading = atan2(y,x); // find the angle + printf("heading after atan2: %f\n",heading); + heading = (heading * 180 / PI); //convert to degree + printf("heading after atan2 (degrees): %f\n",heading); + + //heading += declinationAngle + (BODY_MOUNT_RAD_FIX); + //printf("heading after fixes: %f\n",heading); + + if (heading >0 ) + heading -= 90; // sensor rotated by 90 degrees + else if (heading < 0) + heading+=90; + + //fix for arm sensor mount angle + if(heading > 180) heading -= 180; + else if(heading < 0) heading += 180; + + //---------- map degrees from -180->180 to 0->360 (only positive degrees) ---------- // + // if(heading < 0 && heading >= -180) + // heading += 360; + //-----------------------------------------------------------------------------------// + + + + ////fix for arm sensor mount angle +// if(heading > 360) heading -= 360; +// if(heading < 0) heading += 360; + + + //heading = (heading * 180 / PI); //convert to degree + printf("heading final: %f\n\n",heading); + // printf("heading: %f\n", heading); // debug + + break; + + case 2: // arm + Read_Magnetic_arm(); + heading = atan2(y,x); // find the angle + heading += declinationAngle + Arm_RAD_FIX ; + if(heading < 0) heading += 2*PI; + if(heading > 2*PI) heading -= 2*PI; + heading = (heading * 180 / PI); //convert to degree +// heading += ARM_MOUNT_ANGLE - TargetAngle; + if(heading < 180 ) heading = - heading; + else // 180 <= heading <= 360 + heading = 360 - heading; + break; } - - m_x = x/2; - m_y = y/2; - m_z = z/2; - */ - wait(1); + + return heading; +} - while(1) - { - /* - x = m_x - hmc5883l.getMx()*0.92; - y = m_y - hmc5883l.getMy()*0.92; - z = m_z - hmc5883l.getMz()*0.92; - */ - x = hmc5883l.getMx(); - y = hmc5883l.getMy(); - z = hmc5883l.getMz(); - - heading = atan2(y, x); - if(heading < 0) - heading += 2*PI; - if(heading > 2*PI) - heading -= 2*PI; - - heading = heading * 180 / PI; - - // Correct for when signs are reversed. - //if(heading < 0) - // heading += 2*PI; - //if(heading > 2*PI) - // heading -= 2*PI; - - //while(heading < 0) heading += 360; - //while(heading > 360) heading -= 360; - - - printf("x: %f \t\ty: %f \t\t z: %f \t\t heading: %f \t\r\n", x, y, z, heading); - wait_ms(200); - +int main() +{ + + BT.baud(115200); + Servo.period(0.020); // set PWM period time to 20ms period or 50hz frequency + // hmc_arm.Write(0x02,0x00); // set magnetic sensor on arm to continuous mode + // pc.attach(&DataReceived_Pc_ISR,Serial::RxIrq); //maor + BT.attach(&DataReceived_ISR,Serial::RxIrq); //maor + wait(1); + //globalTimer.start(); + pc.printf("ready"); + //Thread t1(thread1); //start thread1 ARM + //t1.set_priority(osPriorityHigh); + + Thread t2(thread2); //start thread2 BT SEND + t2.set_priority(osPriorityNormal); + + //Thread t3(thread3); //start thread3 BT RECIEVE + //t3.set_priority(osPriorityNormal); + + Servo.pulsewidth_us(2000); + wait(2); + Servo.pulsewidth_us(1500); + wait(2); + Servo.pulsewidth_us(1000); + wait(2); + Servo.pulsewidth_us(1500); + + while(1) { // main is the next thread +// if(pc.readable()) +// { +// int x; +// pc.scanf("%d",&x); +// printf("got:%d\n",x); +// Servo.pulsewidth_us(x); +// } +// } -} +} \ No newline at end of file
diff -r 6bc5f85ca6fa -r aea254b39529 mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue May 24 12:08:14 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#bdd541595fc5
diff -r 6bc5f85ca6fa -r aea254b39529 mbed.bld --- a/mbed.bld Tue May 21 13:48:10 2013 +0000 +++ b/mbed.bld Tue May 24 12:08:14 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/082adc85693f \ No newline at end of file