Jag har försökt slänga ihop en liten höjd och accelerations logger som ska kastas med lite olika former ur en helikopter på fredag. Det mesta har fungerat bra men AD konverteringarna strular. Det har fungerat jättebra med bara en kanal, men såfort jag kollar en i taget av de 7 jag använder så blir alla värden ungefär samma och fel. Det första värdet är ofta rätt (ca 800) men sen minskar det o stannar runt 60-70. se nedan.
Kod: Markera allt
ch: 1. Value: 816 :: ch: 2. Value: 632 :: ch: 3. Value: 496 :: ch: 4. Value: 487 :: ch: 5. Value: 352 :: ch: 6. Value: 334 :: ch: 7. Value: 327 ::
ch: 1. Value: 319 :: ch: 2. Value: 304 :: ch: 3. Value: 287 :: ch: 4. Value: 287 :: ch: 5. Value: 286 :: ch: 6. Value: 255 :: ch: 7. Value: 255 ::
ch: 1. Value: 255 :: ch: 2. Value: 252 :: ch: 3. Value: 231 :: ch: 4. Value: 224 :: ch: 5. Value: 224 :: ch: 6. Value: 224 :: ch: 7. Value: 199 ::
ch: 1. Value: 192 :: ch: 2. Value: 192 :: ch: 3. Value: 192 :: ch: 4. Value: 176 :: ch: 5. Value: 167 :: ch: 6. Value: 167 :: ch: 7. Value: 167 ::
ch: 1. Value: 152 :: ch: 2. Value: 143 :: ch: 3. Value: 152 :: ch: 4. Value: 152 :: ch: 5. Value: 127 :: ch: 6. Value: 127 :: ch: 7. Value: 127 ::
ch: 1. Value: 127 :: ch: 2. Value: 113 :: ch: 3. Value: 112 :: ch: 4. Value: 120 :: ch: 5. Value: 113 :: ch: 6. Value: 99 :: ch: 7. Value: 103 ::
ch: 1. Value: 112 :: ch: 2. Value: 103 :: ch: 3. Value: 96 :: ch: 4. Value: 97 :: ch: 5. Value: 103 :: ch: 6. Value: 88 :: ch: 7. Value: 88 ::
ch: 1. Value: 96 :: ch: 2. Value: 96 :: ch: 3. Value: 79 :: ch: 4. Value: 88 :: ch: 5. Value: 96 :: ch: 6. Value: 79 :: ch: 7. Value: 79 ::
ch: 1. Value: 92 :: ch: 2. Value: 92 :: ch: 3. Value: 71 :: ch: 4. Value: 79 :: ch: 5. Value: 88 :: ch: 6. Value: 71 :: ch: 7. Value: 71 ::
ch: 1. Value: 88 :: ch: 2. Value: 81 :: ch: 3. Value: 71 :: ch: 4. Value: 79 :: ch: 5. Value: 88 :: ch: 6. Value: 71 :: ch: 7. Value: 71 ::
ch: 1. Value: 79 :: ch: 2. Value: 79 :: ch: 3. Value: 63 :: ch: 4. Value: 71 :: ch: 5. Value: 79 :: ch: 6. Value: 63 :: ch: 7. Value: 67 ::
ch: 1. Value: 79 :: ch: 2. Value: 71 :: ch: 3. Value: 63 :: ch: 4. Value: 71 :: ch: 5. Value: 79 :: ch: 6. Value: 63 :: ch: 7. Value: 67 ::
Specs. ATMega644P, drivs på 3.3V. AREF avkopplad mot GND med 0u1F. AVCC är LC kopplad mot VCC 10uH och 0u1F . Allt enligt min tolkning av databladet.
Så vad är inkopplat:
ADC ch: 1. Trycksensor, drivs på 5V. Spänningsdelad utgång, 20k och 39k mot GND.
ADC ch: 2,3,4. Accelerometer X, Y, Z. Analoga utsignaler upp till 3.3V.
ADC ch: 5,6,7. Hänger lösa i detta läge.
UART
ISP
En switch mot PortB pin 1 som om på jordar och startar sen loggern i log läge. Är den ej på så är PortB pin1 uppdragen och den startar i utläsning/debug läge.
Ordnar schema om någon önskar.
Är det någon som har en aning om vad det kan bero på så blir jag evigt tacksam.
Se koden nedan, den är ganska hastigt ihopslängd och i många fall stulen från olika källor så jag ber om ursäkt för hur den ser ut.
Kod: Markera allt
/* Absolute Pressure/Altimeter and Acceleration logger
Johan Juhlén 2010. */
#define F_CPU 8000000// Clock Speed
#define UART_BAUD 19200
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <string.h>
#include "uart.h"
#define ADC_CHANNELS_USED 7
#define PIN_B1 (PINB&1)
//unsigned int EEMEM loggedData[2000];
unsigned int eemem_address = 0;
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
void inits(void);
void dataLog(void);
unsigned int readADC(uint8_t ch);
//set some timer to count seconds.
volatile char buffer[16];
ISR(TIMER1_COMPA_vect)
{
dataLog();
}
int main(void)
{
int i;
int j = 2000;
unsigned int input;
inits();
volatile char buffer[16];
stdout = &mystdout;
for(;;)
{
if (!PIN_B1)
{
TCCR1B |= (1<<WGM12); //CTC
TCCR1B |= (1<<CS12); //Prescaler 1024
TCCR1B |= (1<<CS10); // -'-
TIMSK1 |= (1<<OCIE1A); //interrupt at compare match
OCR1A = 0x0F42; //period = ~1s at 8MHz
sei();
while(1)
{;}
}
printf("Welcome.\n\rPress 'r' to read out memory. (w to do a testwrite to memory WILL ERASE ALL CURRENT DATA!)\n\r> ");
input = uart_get_schar();
printf(input);
if (tolower(input) == 'w')
{
printf("Write\n\r");
unsigned int temp =830;
while (1)
{
printf("temp = %u\n\r", temp);
eeprom_write_word ((uint16_t *)eemem_address, temp);
// sprintf(buffer, "%u", readADC(0));
printf("%u written to EEPROM address %u.\n\r", eeprom_read_word((uint16_t *)eemem_address),eemem_address);
_delay_ms(200);
temp++;
eemem_address = eemem_address +2;
if (eemem_address > 1999)
{
printf("EEPROM FULL\n\r");
while(1);
}
}
}
if (tolower(input) == 'r')
{
printf("Read\n\r");
while (1)
{
printf("Value in EEPROM: %u\n\r", eeprom_read_word((uint16_t *)eemem_address));
_delay_ms(200);
eemem_address = eemem_address +2;
if (eemem_address > 1999)
{
printf("Read out finished.\n\r");
while(1);
}
}
}
if (tolower(input) == 'a')
{
printf("Read out ADC\n\r");
while (1)
{
for (i = 0; i<ADC_CHANNELS_USED; i++)
{
printf("ch: %u. Value: %u :: ",i+1,readADC(i));
_delay_ms(200);
}
printf("\n\r");
}
}
}
}
void dataLog(void)
{
unsigned int i, temp;
for (i = 0; i<ADC_CHANNELS_USED; i++)
{
temp = readADC(i);
eeprom_write_word ((uint16_t *)eemem_address, temp);
eemem_address = eemem_address +2;
if (eemem_address > 1999)
{
printf("EEPROM FULL\n\r");
TIMSK1 &= ~(1<<OCIE1A); // Turn off timer1
while(1);
}
}
}
void inits(void)
{
// Init PORT A
DDRA =0x00; // Inputs
PORTA = 0x00; // Not pulled up
DDRB = 0;
PORTB = 0xFF;
// Init UART
uart_init();
// ADC init
ADMUX |= (1 << REFS0);
ADCSRA |= (1 << ADEN);
return;
}
unsigned int readADC(uint8_t ch)
{
int i;
ADMUX |= ch;
ADCSRA |= (1 << ADSC);
while(ADCSRA & (1<<ADSC));
return ADC;
}