/* APM_ADC.cpp - ADC ADS7844 Library for Ardupilot Mega Code by Jordi Muņoz and Jose Julio. DIYDrones.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. External ADC ADS7844 is connected via Serial port 2 (in SPI mode) TXD2 = MOSI = pin PH1 RXD2 = MISO = pin PH0 XCK2 = SCK = pin PH2 Chip Select pin is PC4 (33) [PH6 (9)] We are using the 16 clocks per conversion timming to increase efficiency (fast) The sampling frequency is 400Hz (Timer2 overflow interrupt) So if our loop is at 50Hz, our needed sampling freq should be 100Hz, so we have an 4x oversampling and averaging. Methods: Init() : Initialization of interrupts an Timers (Timer2 overflow interrupt) Ch(ch_num) : Return the ADC channel value On Ardupilot Mega Hardware: Channel 1 : Gyro Z Channel 2 : Gyro X Channel 3 : Gyro Y Channel 4 : Acc X Channel 5 : Acc Y Channel 6 : Acc Z Channel 7 : Differential pressure sensor */ extern "C" { // AVR LibC Includes #include #include #include "WConstants.h" } #include "APM_ADC.h" // Commands for reading ADC channels on ADS7844 const unsigned char adc_cmd[9]= { 0x87, 0xC7, 0x97, 0xD7, 0xA7, 0xE7, 0xB7, 0xF7, 0x00 }; volatile long adc_value[8]; volatile unsigned char adc_counter[8]; unsigned char ADC_SPI_transfer(unsigned char data) { /* Wait for empty transmit buffer */ while ( !( UCSR2A & (1<>3; // Shift to 12 bits adc_counter[ch]++; // Number of samples } bit_set(PORTC,4); // Disable Chip Select (PIN PC4) //bit_clear(PORTL,6); // To test performance TCNT2 = 104; // 400 Hz } // Constructors //////////////////////////////////////////////////////////////// APM_ADC_Class::APM_ADC_Class() { } // Public Methods ////////////////////////////////////////////////////////////// void APM_ADC_Class::Init(void) { unsigned char tmp; pinMode(ADC_CHIP_SELECT,OUTPUT); digitalWrite(ADC_CHIP_SELECT,HIGH); // Disable device (Chip select is active low) // Setup Serial Port2 in SPI mode UBRR2 = 0; DDRH |= (1<0) result = adc_value[ch_num]/adc_counter[ch_num]; else result = 0; adc_value[ch_num] = 0; // Initialize for next reading adc_counter[ch_num] = 0; sei(); return(result); } // make one instance for the user to use APM_ADC_Class APM_ADC;