mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fragen zu meinem Batterietester


Autor: Huber M. (michael_h784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich habe mir zur Übung einen Batterietester gebaut. Für mignon 1,5v 
batterien.
Dieser soll mir an ADC0 über einen 2K Widerstand die Spannung einlesen. 
Und je nach Zustand eine rote, gelbe oder grüne led an PC1, PC2 oder PC3 
anschalten.

jetzt ist es aber so, das er mir zwischen den Farben (3 ports c) hin und 
herspringt. Mal grün solange er will, dann mal rot, und in den seltesten 
fällen orange.

ich habe auch batterien mit unterschiedlicher Ladung hier liegen, wenn 
ich diese aber dran halte, ändert sich nichts. Berühre ich dann noch 
zusätzlich mit der linken Hand an gnd, und mit der rechten Hand +, dann 
geht es von rot nach grün, hände weg von grün nach rot (spannung der 
batterie 1,5V. laut meinem Code sollte sie ja auf orange schalten.

nun meine Frage was habe ich hier nicht beachtet? Schaltung im bild oben 
aufgezeichnet.

dazu habe ich folgenden code geschrieben.:
#define F_CPU 100000UL
#include <util/delay.h>


#include <avr/io.h>
#include <avr/interrupt.h>

#define newled PINC1
#define  okled PINC2
#define oldled PINC3

#define analogvalue 0
#define leddeelay 2000
float voltage = 0 ;

int main(void)

{   // Ein und Ausgänge konfigurieren
  
    DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
                        

  // Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
  ADMUX = (1<<REFS1)|(1<<ADLAR);  // Refs0 u. Refs1 Referenzspannung // ADLAR bits linksbündig setzen
                                  // AVCC with external capacitor at AREF pin to GND           
  
  ADCSRA = (1<<ADEN) |(1<<ADFR)|   // ADEN bit startet den wandler, ADFR = Freerunningmode
  (1<<ADPS2)| (1<<ADIE);            // Fadc=Fcpu/prescaler=1000000/16=62.5kHz ADPS2 bit//
                                    // Fadc should be between 50kHz and 200kHz
                                    // ADIE Startet ADC complete ISR
  sei();                            // schaltet die ISR FREI
  
  ADCSRA |= (1<<ADSC);              // Startet den Messvorgang je nach gewählter modi
  
  for(;;);                          // Endlosschleife
  // main() wird nie verlassen

  return 0;                         // wird nie ausgeführt

}
// ISR für ADC-wert
ISR(ADC_vect)
{
  
  
  
  
  
  voltage = 0.0048*ADC;  // 5V/1023 = 0.0048
  
  if (voltage >= 1.6)
  {
    PORTC |= (1<<PC1);
    _delay_ms(leddeelay);        // grüne led soll leuchten
    PORTC &= ~(1<<PC1);
  }
  else if (voltage < 1.6 && voltage >1.4)
  {
    PORTC |= (1<<PC2);
    _delay_ms(leddeelay);        // orange led soll leuchten
    PORTC &= ~(1<<PC2);
    
  }
  else if (voltage <= 1.4)
  {
    PORTC |= (1<<PC3);
    _delay_ms(leddeelay);         // rote led soll leuchten
    PORTC &= ~(1<<PC3);
    
  }
  
  
}


grüsse huber

: Verschoben durch Moderator
Autor: ASM Superprofi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und der 2k R zu PC0 hat genau was für einen Sinn?

Autor: hrmpf (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Den hat der TO so von einem x-beliebigen Schaltplan abgemalt und weiß 
selbst nicht, was das soll...

Autor: Bastian W. (jackfrost)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Delay in ner ISR ist nicht gut. Mach die Verarbeitung der LEDs in der 
Main. In der ISR aktualisierst du einfach nur den ADC Wert.
Du kannst dir auch den Floatteil sparen wenn du die Grenzwerte einfach 
als ADC Int ausrechnest.
Bei den LEDs ist es einfacher die einfach nur leuchten zu lassen ohne 
das delay. Einfach die beiden anderen LEDs auf low setzen und der If 
Abfrage fürchte Grenzwerte.

Gruß JackFrost

Autor: Paul B. (paul_baumann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, wie die Beschaltung des Potentiometers aussieht, liegt der ADC 0 
immer auf Masse und das Poti geht zum Teufel, wenn der Schleifer oben 
beim +5V-Anschluss ankommt.

MfG Paul

(Ob das Programm richtig ist, kann ich nicht sagen, weil ich C nicht 
beherrsche und auch nicht beherrschen will.)

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das mit den Delays in der ISR ist nicht schön ...

Hast Du Dir mal das Datenblatt angeschaut? Welche Referenzspannung soll 
es denn sein?

Table 27-2 ADC Voltage Reference Selection
REFS[1:0] Voltage Reference Selection
00 AREF, Internal Vref turned off
01 AVCC with external capacitor at AREF pin
10 Reserved
11 Internal 2.56V Voltage Reference with external capacitor at AREF pin

"Reserved" heißt: Nicht nehmen :-)

Oh Mann - ich hatte nicht gesehen, dass Du es bist. Hartnäckig bist Du 
ja - aber ohne Datenblatt-Studium (und vor allem C-Studium) wird das 
schwierig werden.

: Bearbeitet durch User
Autor: ASM Superprofi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso. Jetzt verstehe ich. Das soll kein missglückter Versuch einer Last 
sein, sondern der TO will die Leerlaufspannung der Batterie messen. Na 
dann....

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ASM Superprofi schrieb:
> Und der 2k R zu PC0 hat genau was für einen Sinn?

zum schutz des uc gegen zu hohen strom , wenn ich die batterie anklemme.

hrmpf schrieb:
> Den hat der TO so von einem x-beliebigen Schaltplan abgemalt und weiß
> selbst nicht, was das soll...

Das ist genau das was ich auf dem Breadboard auf gesteckt habe. Aus 
einem vor mir liegenden Workshop Buch Projekt nr.3 . Nach lauflicht und 
Ampelschaltung.

Dieter F. schrieb:
> Hast Du Dir mal das Datenblatt angeschaut? Welche Referenzspannung soll
> es denn sein?

ja hab ich. Beim Atmega8a steht REFS01 für AVCC with external capacitor 
at AREF pin drinen das habe ich ja gesetzt. Das wollte ich auch.


werde das Ausserhalb der ISR testen. damit ich die delays raus bringe.

Dieter F. schrieb:
> aber ohne Datenblatt-Studium (und vor allem C-Studium) wird das
> schwierig werden.

Datenblatt habe ich wenig probleme. der ADC gibt mir ja einen wert aus 
:-).

C studium, don`t panic :-) hab das buch (C programmieren von anfang an) 
schon begonnen .

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> ja hab ich. Beim Atmega8a steht REFS01 für AVCC with external capacitor
> at AREF pin drinen das habe ich ja gesetzt. Das wollte ich auch.

Nö, Du musst schon richtig Lesen und Verstehen - REFS01 gibt es nicht:

Dieter F. schrieb:
> REFS[1:0] Voltage Reference Selection
> 01 AVCC with external capacitor at AREF pin

REFS1 = 1. Stelle
REFS0 = 2. Stelle

Also muss REFS0 auf 1 gesetzt werden.

Huber M. schrieb:
> Datenblatt habe ich wenig probleme. der ADC gibt mir ja einen wert aus
> :-).

Ja, irgendetwas ... :P

: Bearbeitet durch User
Autor: Ralph S. (jjflash)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
... prinzipiell kann ein "Batteriezustand" nur im belasteten Zustand 
erfasst werden, weil ansonsten ein Spannungsmesser (wie bspw. der ADC 
eines Controllers) extrem viel groesser als der Innenwiderstand der zu 
messenden Zelle ist.

Im unbelasteten Zustand wird ansonsten (fast nur) die U0 der Zelle 
gemessen.

Ich würde bspw. eine Mignonzelle kurzfristig mit ca. mindestens 100mA 
belasten, was einem 150 Ohm Widerstand entspricht (bei Nennspannung der 
Zelle).

Programm im Anhang, die Schwellen für "leer" , "mittel" und "voll" ... 
kann man drüber streiten.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ralf auf allefälle für mich interresant, aber ich werd mich erstmal an 
mein buch halten.

Dieter F. schrieb:
> Nö, Du musst schon richtig Lesen und Verstehen - REFS01 gibt es nicht:

da habe ich mich wohl verschrieben, es gibt natürlich nur das, was im 
Einstellregister steht.

danke.

so jetzt habe ich das ganze nochmal übersichtlicher geschrieben. Und 
ausserhalb der ISR.

Und jetzt glaube ich langsam das bei mir sachen nicht funktionieren die 
bei jeden anderen einfach so funktionieren.

ich dachte mir, wenn ich den ADC- converter mit ISR richtig konfiguriert 
habe, muss ich im zusammen spiel mit der #include <avr/interrupt.h> den 
befehl sei; darunter setzen das er das ganze aktiviert.

dann compilier ich das ganze, danach kommt das dabei raus

Error  1  'sei' undeclared (first use in this function)  C:\Dokumente 
und Einstellungen\Huber\Eigene Dateien\Atmel 
Studio\6.2\GccApplication34\GccApplication34\GccApplication34.c  31  2 
GccApplication34

das kann doch jetzt fast nicht sein oder?
//************ÜBUNGSAUFGABE BATTERIETESTER*********************//


#define F_CPU 100000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define leddeelay 2000
float voltage = 0 ;

// ISR für ADC-wert
ISR(ADC_vect)
{
  ADC;
}
int main(void)

{   // Ein und Ausgänge konfigurieren
  
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
  

// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
  
  ADMUX = (1<<REFS0)|(1<<ADLAR);  

// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
  
  sei; // aktivieertt das ganze
  
while(1)
{
  voltage = 0.0048*ADC;
  
  
  if (voltage >= 1.6)
  {
    PORTC |= (1<<PC1);
    _delay_ms(leddeelay);        // grüne led soll leuchten
    PORTC &= ~(1<<PC1);
  }
  else if (voltage < 1.6 && voltage >1.4)
  {
    PORTC |= (1<<PC2);
    _delay_ms(leddeelay);        // orange led soll leuchten
    PORTC &= ~(1<<PC2);
    
  }
  else if (voltage <= 1.4)
  {
    PORTC |= (1<<PC3);
    _delay_ms(leddeelay);         // rote led soll leuchten
    PORTC &= ~(1<<PC3);
    
  }
  
  
}
}


Autor: HildeK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> das kann doch jetzt fast nicht sein oder?

Doch, es muss heißen
sei();
 statt
sei;

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> // ISR für ADC-wert
> ISR(ADC_vect)
> {
>   ADC;
> }

Was soll das bewirken?

Lese mal nach, was VOLATILE bzw. so definierte Variablen bewirken und 
wozu man diese nutzt :-)

Mit sei; hast Du "verschlimmbessert" - das war im Eingangspost richtig.

Du solltest auch nochmal drüber nachdenken, wie schnell Dein ATMega8a so 
ist und das mit Deiner Angabe in Übereinstimmung bringen ...

: Bearbeitet durch User
Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Was soll das bewirken?
>
> Lese mal nach, was VOLATILE bzw. so definierte Variablen bewirken und
> wozu man diese nutzt :-)

Ok, das heisst in Groben zügen ich muss dem Compiler mitteilen, das sich 
diese variable ausser halb der ISR, und umgekehrt verändern kann. das er 
mir das nicht weg optimiert?

aber mir erschliesst sich jetzt nicht ganz daraus. Wie ich das richtig 
deklariere/definiere. also volatile ist klar, muss ich ihm da noch einen 
Startwert zuweisen zb. 0 ?

[]

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define leddeelay 50
float voltage = 0 ;
volatile  uint8_t ADC; // so frisst er mir das nämlich nicht

// ISR für ADC-wert
ISR(ADC_vect)
{
  ADC = 0;
}
int main(void)[]

Autor: restfet (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
#define F_CPU 100000UL

Möglich, dass dir das hier (auch) einen Strich durch die Rechnung macht? 
Ist mir nur grade aufgefallen, hab deinen restlichen Code noch nicht 
angeschaut.

Aber in deinem neuesten Post hast du das ja schon geändert..

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> Ok, das heisst in Groben zügen ich muss dem Compiler mitteilen, das sich
> diese variable ausser halb der ISR, und umgekehrt verändern kann. das er
> mir das nicht weg optimiert?

Korrekt.

Huber M. schrieb:
> also volatile ist klar, muss ich ihm da noch einen
> Startwert zuweisen zb. 0 ?

Nein, das ist nicht notwendig.

Aber - es soll ein 16-Bit-Wert aus dem Doppel-Register ADC (ohne 
Vorzeichen) übernommen werden (IN DER ISR), welchen Du dann in der 
MAIN-Routine verwenden willst. Daher sollte diese Variable auch als 
uint16_t deklariert werden.

Huber M. schrieb:
> volatile  uint8_t ADC; // so frisst er mir das nämlich nicht

Da hat er Recht, ADC ist ein fest vergebenes Doppel-Register (ADCH und 
ADCL) - Du musst eine eigene Variable -z.B. ADC_WERT definieren und 
verwenden (also den ADC-Wert in diese Variable übernehmen und dann in 
MAIN damit rechnen).

: Bearbeitet durch User
Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich weiss was du meinst

   ADCH           ADCL      = ADC, deshalb uint_16 deshalb ADC wert = 0- 
1023
  00000000      00000000       gibt er aus


volatile  uint16_t ADC;   // oder  ADCH & ADCL aber hier beisst es 
gerade aus
                          // bringt mir immer noch fehler egal ob ich =
                          // davor setze oder nicht
#define ADC_wert = ADC;

//************ÜBUNGSAUFGABE BATTERIETESTER*********************//


#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define leddeelay 50
float voltage = 0 ;
volatile  uint16_t ADC;   // oder  ADCH & ADCL
#define ADC_wert = ADC ;

// ISR für ADC-wert
ISR(ADC_vect)
{

}
int main(void)

{   // Ein und Ausgänge konfigurieren
  
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
  

// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
  
  ADMUX = (1<<REFS0)|(1<<ADLAR);  

// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
  
  sei(); // aktiviertt das ganze
  
while(1)
{
  ADC_wert // wird später als variable richtig verwendet
  
  
  if (voltage >= 1.6)
  {
    PORTC |= (1<<PC1);
    _delay_ms(leddeelay);        // grüne led soll leuchten
    PORTC &= ~(1<<PC1);
  }
  else if (voltage < 1.6 && voltage >1.4)
  {
    PORTC |= (1<<PC2);
    _delay_ms(leddeelay);        // orange led soll leuchten
    PORTC &= ~(1<<PC2);
    
  }
  else if (voltage <= 1.4)
  {
    PORTC |= (1<<PC3);
    _delay_ms(leddeelay);         // rote led soll leuchten
    PORTC &= ~(1<<PC3);
    
  }
  
  
}
}


Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich wollte ich Dir keinen Code vorgeben ...
volatile  uint16_t ADC_wert;   


// ISR für ADC-wert
ISR(ADC_vect)
{
   ADC_wert = ADC;
}

...

while(1)
{
  voltage = 0.0048 * ADC_wert;

...


Autor: restfet (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
volatile  uint16_t ADC;   // oder  ADCH & ADCL
#define ADC_wert = ADC ;

Du kannst die Variable nicht ADC nennen, der Name ist schon fürs 
Ergebnisregister des ADC vergeben.

Machs so und gut ist:
volatile uint16_t ADC_wert;

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
16-Bit Register (ADC, ICR1, OCR1x, TCNT1, UBRR)[Bearbeiten]

Einige der Portregister in den AVR-Controllern sind 16 Bit breit. Im 
Datenblatt sind diese Register üblicherweise mit dem Suffix "L" 
(Low-Byte) und "H" (High-Byte) versehen. Die avr-libc definiert 
zusätzlich die meisten dieser Variablen die Bezeichnung ohne "L" oder 
"H". Auf diese Register kann dann direkt zugegriffen werden. Dies ist 
zum Beispiel der Fall für Register wie ADC oder TCNT1.

Aus: 
https://www.mikrocontroller.net/articles/AVR-GCC-T...

Bitte tue Allen einen Gefallen und arbeite das Tutorial durch.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Aus:
> 
https://www.mikrocontroller.net/articles/AVR-GCC-T...
>
> Bitte tue Allen einen Gefallen und arbeite das Tutorial durch.

werd ich auf jeden fall auch noch machen.

Dieter F. schrieb:
> Eigentlich wollte ich Dir keinen Code vorgeben ...

das verlange ich auch von keinem, das bringt mich nicht weiter. bin dir 
aber dankbar für die tipps. Wo ich nachschlagen kann. Mit der letzten 
Antwort hast du meinen nächste Frage schon beantwortet. Das ist genau 
das, warum ich immer durcheinander komme. Da ich immer meinte hier zb. 
ADC gibt mir schon einen wert von 0-1023 aus (zusammen gefasst aus 
ADCH/ADCL). Und ich muss erst ADC einer Variable zuweisen.

das es ADCH und ADCL register gibt wusste ich alles. Aber nicht das ich 
direkt darauf zugreifen kann. Und mit dem ADLAR bit kann ich links oder 
rechtsbündig wählen. das hat mich total aus dem konzept gebracht. denn 
woher soll unint_16 wissen das ich jetzt genau das ADC register meine, 
wenn ich einfach ""volatile uint16_t ADC_wert;"" zuweise. das kann ich 
mir ja jetzt nochmal durch arbeiten

also noch  mal danke

Autor: Der Andere (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unabhängig von deinen Programmierproblemen:

hast du das beachtet was Paul zu dem Poti gesagt hat?
So beschaltet machst du einen Kurzschluss wenn du den Poti in eine 
Endstellung drehst!
Die Verbindung vom Schleifer zur Masse muss weg!

Weiter wurde oben schon erwähnt, dass man die Batterie belasten muss um 
ein aussagekräftiges Ergebnis zu bekommen. Mindestens 100, besser ca. 
300mA bei Mignon Zellen.

Der beste Batterietester für Mignon und Micro Batterien sind bei mir 
1-zellige Taschenlampen mit guten alten Glühfadenbirnchen.
Wenn die Batterie schwächelt, dann sieht man das sofort am funzeln der 
Lampe.

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das findest Du gut beschrieben hier:

Die Ergebnisregister ADCL und ADCH[Bearbeiten]

Da das Ergebnis des ADC ein 10 Bit Wert ist, passt dieser Wert 
naturgemäß nicht in ein einzelnes Register, das ja bekanntlich nur 8 Bit 
breit ist. Daher wird das Ergebnis in 2 Register ADCL und ADCH abgelegt. 
Standardmäßig (d.h. ADLAR = 0) werden von den 10 Ergebnisbits die 
niederwertigsten 8 im Register ADCL abgelegt und die noch fehlenden 2 
Bits im Register ADCH an den niederwertigsten Bitpositionen gespeichert.

             ADCH                                   ADCL
  +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
                            9   8       7   6   5   4   3   2   1   0
Ist keine 10-bit Genauigkeit gefragt, kann diese Zuordnung aber auch 
geändert werden: Durch Setzen des ADLAR Bits im ADMUX Register wird die 
Ausgabe geändert zu:

             ADCH                                   ADCL
  +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
    9   8   7   6   5   4   3   2       1   0
Auf diese Weise kann das ADC Ergebnis direkt als 8 Bit Zahl 
weiterverarbeitet werden: Die 8 höchstwertigen Bits stehen bereits 
verarbeitungsfertig im Register ADCH zur Verfügung.

Beim Auslesen der ADC-Register ist zu beachten: Immer zuerst ADCL und 
erst dann ADCH auslesen. Beim Zugriff auf ADCL wird das ADCH Register 
gegenüber Veränderungen vom ADC gesperrt. Erst beim nächsten Auslesen 
des ADCH-Registers wird diese Sperre wieder aufgehoben. Dadurch ist 
sichergestellt, daß die Inhalte von ADCL und ADCH immer aus demselben 
Wandlungsergebnis stammen, selbst wenn der ADC im Hintergrund 
selbsttätig weiterwandelt. Das ADCH Register muss ausgelesen werden!

https://www.mikrocontroller.net/articles/AVR-Tutor...

ADLAR setzt man i.d.R., wenn man sowieso nur mit 8 Bite Genauigkeit 
rechnen will (weil z.B. der Wert etwas "wackelt"). Dann reicht natürlich 
eine 8-Bit Variable uint8_t für die Übernahme des Wertes - in diesem 
Fall direkt aus ADCH - aus.

Autor: Dieter W. (dds5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph S. schrieb:
> Ich würde bspw. eine Mignonzelle kurzfristig mit ca. mindestens 100mA
> belasten, was einem 150 Ohm Widerstand entspricht (bei Nennspannung der
> Zelle).

Diese Aussage verstößt gegen das Ohmsche Gesetz.

Autor: Ralph S. (jjflash)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... stimmt, es sind 15 Ohm, sorry
Asche über mein Haupr, es war schon spät.

Autor: Huber M. (michael_h784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten morgen;

Der Andere schrieb:
> Unabhängig von deinen Programmierproblemen:
>
> hast du das beachtet was Paul zu dem Poti gesagt hat?
> So beschaltet machst du einen Kurzschluss wenn du den Poti in eine
> Endstellung drehst!
> Die Verbindung vom Schleifer zur Masse muss weg!

ja habe ich, das habe ich peinlicherweise falsch gezeichnet.

Der Andere schrieb:
> Weiter wurde oben schon erwähnt, dass man die Batterie belasten muss um
> ein aussagekräftiges Ergebnis zu bekommen. Mindestens 100, besser ca.
> 300mA bei Mignon Zellen.

ja das habe ich verstanden. Aber ich glaube, ich habe hier noch ein 
grundliegendes Problem, mit der Beschaltung von ADC0 eingang. In meinem 
Verständis. Zu nachfolgenden Code

Bild 1 , wie hier zu sehen ist habe ich das Poti als Spannungsteiler auf 
ca. 0.4V eingestellt. Im bild leuchtet die Grüne Led, laut Code sollte 
doch die Rote leuchten ?

Bild 2 hier habe ich es auf ca. 1.2V eingestellt, dann sollte doch die 
orange Led leuchten? Habe ich hier beim Anschluss an den analogen 
Eingang, oder doch im Code etwas nicht richtig verstanden?
//************ÜBUNGSAUFGABE BATTERIETESTER*********************//


#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define leddeelay 250

float voltage = 0;

volatile  uint16_t ADC_Wert;   


// ISR für ADC-wert
ISR(ADC_vect)
{
ADC_Wert = ADC;
}
int main(void)

{   // Ein und Ausgänge konfigurieren
  
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
  

// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
  
  ADMUX = (1<<REFS0)|(1<<ADLAR);  

// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
  
  sei(); // aktiviertt das ganze
  
while(1)
{
  voltage = 0.0048 * ADC_Wert;       // 5V / 1023 = 0.0048 um die Schritte aufzuteilen
  
  if (voltage >= 1.6)
  {
    PORTC |= (1<<PC1);           // gleich oder grösser 1.6V
    _delay_ms(leddeelay);        // grüne led soll leuchten
    PORTC &= ~(1<<PC1);
  }
  else if (voltage < 1.6 && voltage > 0.9)
  {
    PORTC |= (1<<PC2);           // kleiner  1.6V und grösser 0.9V
    _delay_ms(leddeelay);        // orange led soll leuchten
    PORTC &= ~(1<<PC2);
    
  }
  else if (voltage <= 0.9)
  {
    PORTC |= (1<<PC3);            // kleiner 0.9V 
    _delay_ms(leddeelay);         // rote led soll leuchten
    PORTC &= ~(1<<PC3);
    
  }
  
  
}
}


Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> Und mit dem ADLAR bit kann ich links oder
> rechtsbündig wählen. das hat mich total aus dem konzept gebracht. denn
> woher soll unint_16 wissen das ich jetzt genau das ADC register meine,
> wenn ich einfach ""volatile uint16_t ADC_wert;"" zuweise. das kann ich
> mir ja jetzt nochmal durch arbeiten

Huber M. schrieb:
> // Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
>
>   ADMUX = (1<<REFS0)|(1<<ADLAR);

Scheinbar ist das noch nicht passiert.

-> Beitrag "Re: Fragen zu meinem Batterietester"

: Bearbeitet durch User
Autor: Arduinoquäler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> Bild 2 hier habe ich es auf ca. 1.2V eingestellt, dann sollte doch die
> orange Led leuchten? Habe ich hier beim Anschluss an den analogen
> Eingang, oder doch im Code etwas nicht richtig verstanden?

Ich finde du solltest dazu übergehen dir mittels serieller
(RS232/USB) Schnittstelle einen besseren Einblick zu
verschaffen was im Controller vorgeht. Der dazugehörige Software-
aufwand ist minimal und du kannst damit weitaus mehr "debuggen",
insbesondere hier ADC Werte ausgeben und evtl. den Controller
mittels PC-Tastatur kommandieren/steuern.

Was du an Hardware brauchst ist sowas:

Ebay-Artikel Nr. 201482917436

(für dein Steckbrett ganz gut geeignet)

Autor: Paul B. (paul_baumann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduinoquäler schrieb:
> Ich finde du solltest dazu übergehen dir mittels serieller
> (RS232/USB) Schnittstelle einen besseren Einblick zu
> verschaffen was im Controller vorgeht.

Da gebe ich Dir Recht. Es ist immer noch schneller erledigt, sich 
seriell eine Variable oder ein Zwischenergebnis auf den Rechner ausgeben 
zu lassen, als etliche Stunden zu spekulieren, was los ist.

MfG Paul

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.