Bryan's Posts (5)

Sort by

Airspeed

Now onto trying to get the differential pressure sensor to do... something. I have the Ardupilot Shield alone with both 3.3v and 5v attached. Analog 3 on the Shield is connected to analog 0 on an Atmega328. Took some trial and error to get the code to read something meaningful (I'm new to this, obviously), and after that was on to road testing. I got the pitot tube from an R/C website, but don't remember which. Here's some redneck engineering at its finest:

/yes, that's masking tape (duct leaves residue) and a stickLiving in the desert, it was windy today. About 25mph with 33mph gusts. Fortunately it was traveling due east, and all the roads are N-S-E-W. So I did a few trials east and west (head and downwind) at the same velocity, then the same thing for north and south (crosswind). I played around with the data for a little bit, and found that the best results came from averaging each run, and then splitting the difference with its opposite. Came up with this graph of results:

Since there was a significant beta with respect to the airflow on the north/south runs, you can see that the pressure difference is less. Makes sense to me at least. So for the fit, I chose the headwind/downwind curve. Something I've noticed about real aircraft (analog and digital birds), you need about 40kts to get a decent airspeed. Same applies to this model. Here's my code:int analogPin = 0;int pressure;float velocity;void setup(){Serial.begin(9600);}void loop(){pressure = analogRead(analogPin);velocity = 2.15314 * (float)pressure - 509.48572;if (velocity < 40){velocity = 0;}Serial.print("Counts: ");Serial.print(pressure);Serial.print(", velocity est: ");Serial.print(velocity);Serial.println("mph");delay (1000);}Now the only thing remaining is to be able to read the GPS data, put it into an algorithm and then I'll be able to calculate the wind speed and direction while the aircraft is flying (one of my primary goals for this system). But considering what I've learned today, higher velocity will equate to more accurate wind speed measurements, so I'll have to account for this when building the airframe. Also, probably going to go out and repeat this test when there's no wind out.
Read more…

Compass, Baro Alt, and Temp Code

If anyone's interested, here's the code I used, slightly modified and spliced from the internet. This is for the SCP1000-D01, with my temperature running about 35 degrees F hot which for now I'm attributing to the heating from the amperage:// define spi bus pins#define SLAVESELECT 10 //CSB#define SPICLOCK 13 //SCK#define DATAOUT 11 //MOSI#define DATAIN 12 //MISO#define UBLB(a,b) ( ( (a) << 8) | (b) )#define UBLB19(a,b) ( ( (a) << 16 ) | (b) )//Addresses#define REVID 0x00 //ASIC Revision Number#define OPSTATUS 0x04 //Operation Status#define STATUS 0x07 //ASIC Status#define START 0x0A //Constant Readings#define PRESSURE 0x1F //Pressure 3 MSB#define PRESSURE_LSB 0x20 //Pressure 16 LSB#define TEMP 0x21 //16 bit tempchar rev_in_byte;int temp_in;unsigned long pressure_lsb;unsigned long pressure_msb;unsigned long temp_pressure;unsigned long pressure;float altitude;void setup(){byte clr;pinMode(DATAOUT, OUTPUT);pinMode(DATAIN, INPUT);pinMode(SPICLOCK,OUTPUT);pinMode(SLAVESELECT,OUTPUT);digitalWrite(SLAVESELECT,HIGH); //disable deviceSPCR = B01010011; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (500kHz)clr=SPSR;clr=SPDR;delay(10);Serial.begin(9600);delay(500);Serial.println("Initialize High Speed Constant Reading Mode");write_register(0x03,0x09);}void loop(){rev_in_byte = read_register(REVID);pressure_msb = read_register(PRESSURE);pressure_msb &= B00000111;pressure_lsb = read_register16(PRESSURE_LSB);pressure_lsb &= 0x0000FFFF;pressure = UBLB19(pressure_msb, pressure_lsb);pressure /= 4;altitude = (1 - pow((float)pressure/101325,0.19025515825))*(288.15/0.00199074074);Serial.print("Altitude ft [");Serial.print(altitude);Serial.println("]");temp_in = read_register16(TEMP);temp_in = temp_in / 20;temp_in = 1.8 * temp_in - 3;Serial.print("TEMP F [");Serial.print(temp_in , DEC);Serial.println("]");delay(1500);}char spi_transfer(volatile char data){SPDR = data; // Start the transmissionwhile (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission{};return SPDR; // return the received byte}char read_register(char register_name){char in_byte;register_name <<= 2;register_name &= B11111100; //Read commanddigitalWrite(SLAVESELECT,LOW); //Select SPI Devicespi_transfer(register_name); //Write byte to devicein_byte = spi_transfer(0x00); //Send nothing, but we should get back the register valuedigitalWrite(SLAVESELECT,HIGH);delay(10);return(in_byte);}float read_register16(char register_name){byte in_byte1;byte in_byte2;float in_word;register_name <<= 2;register_name &= B11111100; //Read commanddigitalWrite(SLAVESELECT,LOW); //Select SPI Devicespi_transfer(register_name); //Write byte to devicein_byte1 = spi_transfer(0x00);in_byte2 = spi_transfer(0x00);digitalWrite(SLAVESELECT,HIGH);in_word = UBLB(in_byte1,in_byte2);return(in_word);}void write_register(char register_name, char register_value){register_name <<= 2;register_name |= B00000010; //Write commanddigitalWrite(SLAVESELECT,LOW); //Select SPI devicespi_transfer(register_name); //Send register locationspi_transfer(register_value); //Send value to record into registerdigitalWrite(SLAVESELECT,HIGH);}/-------------------------------------------------------------------------------------------------------------------------------This is the code I used to get a decent compass heading. There's a lot of extra fluff in this code, and its not modified at all:#include#includeint magReading = 0;int XmagValue = 0;int YmagValue = 0;int Azimuth = 0;void setup(){Serial.begin(9600);Wire.begin();}void magRead(int outputMode){// int HMC6352Address = 0x42;// Shift the device's documented slave address (0x42) 1 bit right// This compensates for how the TWI library only wants the// 7 most significant bits (with the high bit padded with 0)// slaveAddress = HMC6352Address >> 1; // This results in 0x21 as the address to pass to TWIint slaveAddress = 0x21; // This is calculated from HMC6352's address, see comments aboveint ramDelay = 100; // us, delay between a RAM write command and its effect, at least 70usint getDelay = 10; // ms, delay between a get data command and its effect, at least 6msbyte magData[2];int i;switch (outputMode){case 0:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x00); // 0x00 for Heading modeWire.endTransmission();break;case 1:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x03); // 0x03 for Magnetometer X modeWire.endTransmission();break;case 2:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x04); // 0x04 for Magnetometer Y modeWire.endTransmission();break;default:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x00); // default to Heading modeWire.endTransmission();}delayMicroseconds(ramDelay); // RAM write needs 70 microseconds to respondWire.beginTransmission(slaveAddress);Wire.send("A"); // The "Get Data" commandWire.endTransmission();delay(getDelay); // Get Data needs 6 milliseconds to respondWire.requestFrom(slaveAddress, 2); // Request the 2 byte data (MSB comes first)i = 0;while(Wire.available() && i < 2){magData[i] = Wire.receive();i++;}magReading = magData[0]*256 + magData[1];}void loop(){magRead(0);Azimuth = magReading;magRead(1);XmagValue = magReading;magRead(2);YmagValue = magReading;Serial.print("Mag X: ");Serial.print(XmagValue);Serial.print(" Mag Y: ");Serial.print(YmagValue);Serial.print(" Azimuth: ");Serial.print(-int(atan2(YmagValue,XmagValue)*57));Serial.print(" degrees ");Serial.print(int(Azimuth/10));Serial.println(" degrees ");delay(500);}
Read more…

Goal

My goal with this project: To be able to accurately compute winds and take an infrared picture at a specific location.Future add-ons: Bluetooth programmable via iPod touch or something similar, streaming video, near silent operation.Price goal: <$1k for completed system.My pedigree: Pilot, ME/EE/AE/Math degrees from a school you've never heard of.
Read more…

Purchase list

I have no idea what I'm doing at this point. Here's the list of stuff I got, just based on the ArduPilot:https://www.sparkfun.com/commerce/product_info.php?products_id=8785https://www.sparkfun.com/commerce/product_info.php?products_id=465https://www.sparkfun.com/commerce/product_info.php?products_id=9115https://www.sparkfun.com/commerce/product_info.php?products_id=116https://www.sparkfun.com/commerce/product_info.php?products_id=117https://www.sparkfun.com/commerce/product_info.php?products_id=743https://www.sparkfun.com/commerce/product_info.php?products_id=7915http://store.diydrones.com/ProductDetails.asp?ProductCode=BR-0002-10Got a breadboard and wires from Radioshack to help with prototyping. Still need the FMA X-Y sensor, and possibly a Z sensor, but I'm a n00b, and not quite sure what I need at this point.Also need to find some foam to build the airframe, electric motors and metal gear servos.
Read more…