Forum: Mikrocontroller und Digitale Elektronik Fragen zu meinem Batterietester


von Huber M. (michael_h784)


Angehängte Dateien:

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.:
1
#define F_CPU 100000UL
2
#include <util/delay.h>
3
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
8
#define newled PINC1
9
#define  okled PINC2
10
#define oldled PINC3
11
12
#define analogvalue 0
13
#define leddeelay 2000
14
float voltage = 0 ;
15
16
int main(void)
17
18
{   // Ein und Ausgänge konfigurieren
19
  
20
    DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
21
                        
22
23
  // Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
24
  ADMUX = (1<<REFS1)|(1<<ADLAR);  // Refs0 u. Refs1 Referenzspannung // ADLAR bits linksbündig setzen
25
                                  // AVCC with external capacitor at AREF pin to GND           
26
  
27
  ADCSRA = (1<<ADEN) |(1<<ADFR)|   // ADEN bit startet den wandler, ADFR = Freerunningmode
28
  (1<<ADPS2)| (1<<ADIE);            // Fadc=Fcpu/prescaler=1000000/16=62.5kHz ADPS2 bit//
29
                                    // Fadc should be between 50kHz and 200kHz
30
                                    // ADIE Startet ADC complete ISR
31
  sei();                            // schaltet die ISR FREI
32
  
33
  ADCSRA |= (1<<ADSC);              // Startet den Messvorgang je nach gewählter modi
34
  
35
  for(;;);                          // Endlosschleife
36
  // main() wird nie verlassen
37
38
  return 0;                         // wird nie ausgeführt
39
40
}
41
// ISR für ADC-wert
42
ISR(ADC_vect)
43
{
44
  
45
  
46
  
47
  
48
  
49
  voltage = 0.0048*ADC;  // 5V/1023 = 0.0048
50
  
51
  if (voltage >= 1.6)
52
  {
53
    PORTC |= (1<<PC1);
54
    _delay_ms(leddeelay);        // grüne led soll leuchten
55
    PORTC &= ~(1<<PC1);
56
  }
57
  else if (voltage < 1.6 && voltage >1.4)
58
  {
59
    PORTC |= (1<<PC2);
60
    _delay_ms(leddeelay);        // orange led soll leuchten
61
    PORTC &= ~(1<<PC2);
62
    
63
  }
64
  else if (voltage <= 1.4)
65
  {
66
    PORTC |= (1<<PC3);
67
    _delay_ms(leddeelay);         // rote led soll leuchten
68
    PORTC &= ~(1<<PC3);
69
    
70
  }
71
  
72
  
73
}

grüsse huber

: Verschoben durch User
von ASM Superprofi (Gast)


Lesenswert?

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

von hrmpf (Gast)


Lesenswert?

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

von Bastian W. (jackfrost)


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

von Paul B. (paul_baumann)


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.)

von Dieter F. (Gast)


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.

von ASM Superprofi (Gast)


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....

von Huber M. (michael_h784)


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 .

von Dieter F. (Gast)


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

von Ralph S. (jjflash)


Angehängte Dateien:

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.

von Huber M. (michael_h784)


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?
1
//************ÜBUNGSAUFGABE BATTERIETESTER*********************//
2
3
4
#define F_CPU 100000UL
5
#include <util/delay.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#define leddeelay 2000
9
float voltage = 0 ;
10
11
// ISR für ADC-wert
12
ISR(ADC_vect)
13
{
14
  ADC;
15
}
16
int main(void)
17
18
{   // Ein und Ausgänge konfigurieren
19
  
20
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
21
  
22
23
// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
24
  
25
  ADMUX = (1<<REFS0)|(1<<ADLAR);  
26
27
// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
28
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
29
  
30
  sei; // aktivieertt das ganze
31
  
32
while(1)
33
{
34
  voltage = 0.0048*ADC;
35
  
36
  
37
  if (voltage >= 1.6)
38
  {
39
    PORTC |= (1<<PC1);
40
    _delay_ms(leddeelay);        // grüne led soll leuchten
41
    PORTC &= ~(1<<PC1);
42
  }
43
  else if (voltage < 1.6 && voltage >1.4)
44
  {
45
    PORTC |= (1<<PC2);
46
    _delay_ms(leddeelay);        // orange led soll leuchten
47
    PORTC &= ~(1<<PC2);
48
    
49
  }
50
  else if (voltage <= 1.4)
51
  {
52
    PORTC |= (1<<PC3);
53
    _delay_ms(leddeelay);         // rote led soll leuchten
54
    PORTC &= ~(1<<PC3);
55
    
56
  }
57
  
58
  
59
}
60
}

von HildeK (Gast)


Lesenswert?

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

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

von Dieter F. (Gast)


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 ...

von Huber M. (michael_h784)


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)[]

von restfet (Gast)


Lesenswert?

Huber M. schrieb:
1
#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..

von Dieter F. (Gast)


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:
1
> 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).

von Huber M. (michael_h784)


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;

1
//************ÜBUNGSAUFGABE BATTERIETESTER*********************//
2
3
4
#define F_CPU 1000000UL
5
#include <util/delay.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#define leddeelay 50
9
float voltage = 0 ;
10
volatile  uint16_t ADC;   // oder  ADCH & ADCL
11
#define ADC_wert = ADC ;
12
13
// ISR für ADC-wert
14
ISR(ADC_vect)
15
{
16
17
}
18
int main(void)
19
20
{   // Ein und Ausgänge konfigurieren
21
  
22
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
23
  
24
25
// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
26
  
27
  ADMUX = (1<<REFS0)|(1<<ADLAR);  
28
29
// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
30
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
31
  
32
  sei(); // aktiviertt das ganze
33
  
34
while(1)
35
{
36
  ADC_wert // wird später als variable richtig verwendet
37
  
38
  
39
  if (voltage >= 1.6)
40
  {
41
    PORTC |= (1<<PC1);
42
    _delay_ms(leddeelay);        // grüne led soll leuchten
43
    PORTC &= ~(1<<PC1);
44
  }
45
  else if (voltage < 1.6 && voltage >1.4)
46
  {
47
    PORTC |= (1<<PC2);
48
    _delay_ms(leddeelay);        // orange led soll leuchten
49
    PORTC &= ~(1<<PC2);
50
    
51
  }
52
  else if (voltage <= 1.4)
53
  {
54
    PORTC |= (1<<PC3);
55
    _delay_ms(leddeelay);         // rote led soll leuchten
56
    PORTC &= ~(1<<PC3);
57
    
58
  }
59
  
60
  
61
}
62
}

von Dieter F. (Gast)


Lesenswert?

Eigentlich wollte ich Dir keinen Code vorgeben ...
1
volatile  uint16_t ADC_wert;   
2
3
4
// ISR für ADC-wert
5
ISR(ADC_vect)
6
{
7
   ADC_wert = ADC;
8
}
9
10
...
11
12
while(1)
13
{
14
  voltage = 0.0048 * ADC_wert;
15
16
...

von restfet (Gast)


Lesenswert?

Huber M. schrieb:
1
volatile  uint16_t ADC;   // oder  ADCH & ADCL
2
#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:
1
volatile uint16_t ADC_wert;

von Dieter F. (Gast)


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-Tutorial#16-Bit_Register_.28ADC.2C_ICR1.2C_OCR1x.2C_TCNT1.2C_UBRR.29

Bitte tue Allen einen Gefallen und arbeite das Tutorial durch.

von Huber M. (michael_h784)


Lesenswert?

Dieter F. schrieb:
> Aus:
> 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#16-Bit_Register_.28ADC.2C_ICR1.2C_OCR1x.2C_TCNT1.2C_UBRR.29
>
> 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

von Der Andere (Gast)


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.

von Dieter F. (Gast)


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-Tutorial:_ADC#Die_Ergebnisregister_ADCL_und_ADCH

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.

von Dieter W. (dds5)


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.

von Ralph S. (jjflash)


Lesenswert?

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

von Huber M. (michael_h784)


Angehängte Dateien:

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?
1
//************ÜBUNGSAUFGABE BATTERIETESTER*********************//
2
3
4
#define F_CPU 1000000UL
5
#include <util/delay.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
9
#define leddeelay 250
10
11
float voltage = 0;
12
13
volatile  uint16_t ADC_Wert;   
14
15
16
// ISR für ADC-wert
17
ISR(ADC_vect)
18
{
19
ADC_Wert = ADC;
20
}
21
int main(void)
22
23
{   // Ein und Ausgänge konfigurieren
24
  
25
  DDRC = (1<<PD1) | (1<<PD2) |(1<<PD3);
26
  
27
28
// Kanal waehlen kein bit = kanal ADC0, (1<<MUX1) = ADC1 usw...
29
  
30
  ADMUX = (1<<REFS0)|(1<<ADLAR);  
31
32
// ADEN = Ein ADFR = FREERUN ADPS" prescaler 16 ISR AKTIVE ADSC startet erste wandlung
33
  ADCSRA = (1<<ADEN) |(1<<ADFR)| (1<<ADPS2)| (1<<ADIE)|(1<<ADSC);            
34
  
35
  sei(); // aktiviertt das ganze
36
  
37
while(1)
38
{
39
  voltage = 0.0048 * ADC_Wert;       // 5V / 1023 = 0.0048 um die Schritte aufzuteilen
40
  
41
  if (voltage >= 1.6)
42
  {
43
    PORTC |= (1<<PC1);           // gleich oder grösser 1.6V
44
    _delay_ms(leddeelay);        // grüne led soll leuchten
45
    PORTC &= ~(1<<PC1);
46
  }
47
  else if (voltage < 1.6 && voltage > 0.9)
48
  {
49
    PORTC |= (1<<PC2);           // kleiner  1.6V und grösser 0.9V
50
    _delay_ms(leddeelay);        // orange led soll leuchten
51
    PORTC &= ~(1<<PC2);
52
    
53
  }
54
  else if (voltage <= 0.9)
55
  {
56
    PORTC |= (1<<PC3);            // kleiner 0.9V 
57
    _delay_ms(leddeelay);         // rote led soll leuchten
58
    PORTC &= ~(1<<PC3);
59
    
60
  }
61
  
62
  
63
}
64
}

von Dieter F. (Gast)


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"

von Arduinoquäler (Gast)


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:

http://www.ebay.de/itm/RS232-USB-Adapter-Kabel-IC-PL2303HX-5V-TTL-Seriell-Pegel-fur-Arduino-/201482917436?hash=item2ee951563c:g:~kAAAOSw0RpXlbsA

(für dein Steckbrett ganz gut geeignet)

von Paul B. (paul_baumann)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.