2010-08-08 -- 2010-08-15
Under veckan som gått har jag fixat ihop nya tempgivare för ROV:n så nu finns både en internt och en extern fungerande. Det är något helskumt (dvs. något jag inte fattar

) med ADC:n. Jag använder 5 kanaler och läser av dessa i en följd med single conversion mode (dvs. läser en, väntar tills konverteringen är klar, läser den andra, väntar etc.) . Det konstiga är att den första kanalen jag läser av får alldeles för låga värden men de efterföljande 4 kanalerna fungerar felfritt. ADC läser jag ung. var 50 ms. Jag har provat att läsa av kanalerna i olika följder, jag har också bytt plats rent hårdvarumässigt, jag har mätt på första kanalen med multimetern och får en korrekt spänningsnivå men likt förbenat är fortfarande alltid första kanalen jag läser av som strular. Om någon har en idé vad detta kan vara eller har upplevt något liknande är jag nyfiken på vad du gjorde för att få det att fungera.
Så här ser den delen av koden ut som hanterar ADC:
Kod: Markera allt
/* ad.c
*
* Copyright(c) 2010 Jonas Jarvoll (jonas@hobbytronik.se)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "global.h"
#include "ad.h"
//////////////////////////////////////////////////////////////////
//
// S T A T I C F U N C T I O N S
//
//////////////////////////////////////////////////////////////////
// Read out the specified analog channel to 10 bits
static uint16_t analog10(uint8_t channel)
{
uint16_t result;
// Begin by setting up the MUX so it knows which channel
// to connect to the ADC:
// Clear the channel selection (low 5 bits in ADMUX)
ADMUX &= ~0x1F;
// Select the specified channel
ADMUX |= channel;
// Now we initiate a conversion by telling the ADC's
// control register to start conversion (ADSC):
// ADC start conversion
ADCSRA |= (1 << ADSC);
// We wait for conversion to complete by watching the
// ADSC bit on the ADCSRA register. When it goes away,
// the conversion is done:
while (bit_is_set(ADCSRA, ADSC));
// Since we're reading out ten bits, we have to read
// the results out of two different registers: ADCL for
// the low byte, and ADCH for the high byte. Caution
// here: We have to read ADCL before we read ADCH.
// Since they're both just bytes, we have to shift the
// high byte over by 8-bits and or the two together
// to make the full 10-bit value:
result = ADCL;
result |= (ADCH << 8);
return result; // read ADC (full 10 bits);
}
//////////////////////////////////////////////////////////////////
//
// F U N C T I O N S
//
//////////////////////////////////////////////////////////////////
void ad_init()
{
// Use the external AVref (connected to +5 V)
ADMUX = (1 << REFS0);
// Define how fast the conversions are done.
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz
ADCSRA |= (1 << ADEN); // Enable ADC
}
// And now for the maximum in cheesiness: How do you do an
// 8-bit conversion if you're in 10-bit mode? Simple! Do a
// 10-bit conversion and ditch the two least significant bits.
// Laugh all you want, that's how AVRLIB does it, too.
// Read out the specified analog channel to 8 bits
uint16_t ad_read(uint8_t channel)
{
return analog10(channel);
}
Initeringen sker en gång genom ett anrop till
ad_init. Därefter sker avläsningen av resp. kanal med funktionen
ad_read. Koden är mer eller mindre tagen direkt från Orangutan biblioteket. Processorn är en AtMega128 som jag klockar i 16 MHz. Rent kodmässigt är det alltså ingen skillnad att läsa av första kanalen eller läsa av andra kanalen vilket gör problemet ännu skummare i mina ögon.
Hm, det blev lite mer text än vad jag avsåg. Jaja, om någon har varit med om detta tidigare så är jag intresserad att höra det!
Eftersom jag aldrig kom på vad som var fel gör jag helt enkelt så att jag läser första kanalen två gånger och slänger bort första värdet. Då får jag in ett hyfsat bra värde (det är fortfarande lite lågt men är tillräckligt bra).
Jag har även beställt hem större säkringar, 10 A och 12.5 A. Efter moget övervägande satte jag in 12.5 A säkringen i ROV:en.
Sedan blev det en ny tripp till sjön. Denna gång var jag beredd med videokameran.
Här hittar du den. Lite mer action än i den förra!
Men slutet är lite tragiskt....