*/ * Written by Charlie Roberts 2006 * HMC6352_read_heading function taken from: * https://www.ccsinfo.com/forum/viewtopic.php?t=27179&highlight=hmc6352 * * target for the PIC 18F452 using the CCS PIC C Compiler * */ #include <18F452.H> #device ADC=8 #fuses EC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP #use delay(clock=20000000) #use rs232(stream=TERM, baud=9600, xmit=PIN_D2, rcv=PIN_D3,PARITY=N, BITS=8,INVERT) #use I2C (master, sda=PIN_C3, scl=PIN_D0, FORCE_HW) #define HMC6352_I2C_WRITE_ADDRESS 0x42 #define HMC6352_I2C_READ_ADDRESS 0x43 #define HMC6352_GET_DATA_COMMAND 0x41 // Read the compass heading. This is in units // of 1/10's of a degree, from 0 to 3599. int16 HMC6352_read_heading(void) { int8 lsb; int8 msb; i2c_start(); i2c_write(HMC6352_I2C_WRITE_ADDRESS); i2c_write(HMC6352_GET_DATA_COMMAND); i2c_stop(); delay_ms(7); // Allow 1 ms extra for safety i2c_start(); i2c_write(HMC6352_I2C_READ_ADDRESS); msb = i2c_read(); lsb = i2c_read(0); i2c_stop(); return (((int16)lsb | ((int16)msb << 8)) / 10); } int16 xTiltChange(void) { int16 xHeadingChangeAmount; unsigned int16 xTilt; int16 xTiltAmount; set_adc_channel(3); delay_us(30); xTilt = read_adc(); fprintf(TERM, "X tilt = %lu || ", xTilt); if(xTilt > 128) { xTiltAmount = 128 - (255 - xTilt); if(xTiltAmount > 1) { xHeadingChangeAmount = xTiltAmount * -2.1; }else{ xHeadingChangeAmount = 0; } }else{ xTiltAmount = 128 - xTilt; xHeadingChangeAmount = xTiltAmount * 2.1; } fprintf(TERM, "X Tilt Amount =%lu || ", xTiltAmount); fprintf(TERM, "X HeadingChangeAmount = %li\n\r", xHeadingChangeAmount); return xHeadingChangeAmount; } int16 yTiltChange(void) { int16 yHeadingChangeAmount; unsigned int16 yTilt; int16 yTiltAmount; set_adc_channel(2); delay_us(30); yTilt = read_adc(); fprintf(TERM, "Y tilt = %lu || ", yTilt); if(yTilt < 128) { yTiltAmount = 128 - yTilt; if(yTiltAmount > 1) { yHeadingChangeAmount = yTiltAmount * 1.75 ; }else{ yHeadingChangeAmount = 0; } }else{ yTiltAmount = 128 - (255 - yTilt); yHeadingChangeAmount = yTiltAmount * -1; } if(yTiltAmount == 0 || yTiltAmount == 1 || yTiltAmount == -1) { output_high(PIN_D3); } fprintf(TERM, "Y TiltAmount =%lu || ", yTiltAmount); fprintf(TERM, "Y HeadingChangeAmount = %li\n\r", yHeadingChangeAmount); return yHeadingChangeAmount; } int16 getStartHeading() { int16 startHeading; startHeading = HMC6352_read_heading(); fprintf(TERM, "Heading in degrees = %lu\n\r", startHeading); startHeading += yTiltChange(); startHeading += xTiltChange(); if(startHeading > 359) { startHeading = startHeading - 360; }else if (startHeading < 0) { startHeading = 360 + startHeading; } fprintf(TERM, "\n\r\n\r"); fprintf(TERM, "=====================================================\n\r"); fprintf(TERM, "Thank you. Your front center position is %li degrees.\n\r", startHeading); fprintf(TERM, "=====================================================\n\r"); fprintf(TERM, "\n\r\n\r"); return startHeading; } //=================================== void main() { int16 heading; int16 finalHeading; int16 centerHeading; int1 isPressed; setup_adc_ports(ALL_ANALOG); setup_adc( ADC_CLOCK_INTERNAL ); output_high(PIN_D1); fprintf(TERM, "Please orient the controller towards the front center of your space."); fprintf(TERM, "Make sure the controller is level and press the fire button.\n\r\n\r"); while(!input(PIN_D5)); centerHeading = getStartHeading(); delay_ms(2000); isPressed = 0; while(1) { if(input(PIN_D5) && isPressed == 0) { isPressed = 1; heading = HMC6352_read_heading(); fprintf(TERM, "Heading in degrees = %lu\n\r", heading); finalHeading = heading + yTiltChange(); finalHeading += xTiltChange(); fprintf(TERM, "1: final heading before center adjustment = %li\n\r", finalHeading); finalHeading -= centerHeading; fprintf(TERM, "2: final heading after center adjustment = %li\n\r", finalHeading); if(finalHeading > 359 && (finalHeading >> 15) != 1) { fprintf(TERM, "3: final heading wrapped to 0+ = %li\n\r", finalHeading); finalHeading = finalHeading - 360; }else if ((finalHeading >> 15) == 1) { fprintf(TERM, "4: final heading wrapped to 360- = %li\n\r", finalHeading); finalHeading = 360 + finalHeading; } /*if(finalHeading > 359) { finalHeading = abs(finalHeading) - 360; }*/ fprintf(TERM, "FINAL HEADING = %li\n\r\n\r", finalHeading); //delay_ms(2000); }else if(!input(PIN_D5)) { //fprintf(TERM, "button released"); isPressed = 0; } } }