Fragen zu meinem Batterietester

OP #4728497
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
Angehängte Dateien:
#4728623
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
Gast #4728712
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.
OP #4728853
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 .
Gast #4728879
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
#4729098
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.
Angehängte Dateien:
OP #4729331
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
}
Gast #4729350
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 ...
OP #4729437
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)[]
Gast #4729461
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).
OP #4729525
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
}
Gast #4729532
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
...
Gast #4729563
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.
OP #4729666
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
Gast #4729675
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.
Gast #4729677
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.
OP #4735050
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
}
Angehängte Dateien:
Gast #4735157
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"
Gast #4735386
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)
#4735577
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren