Forum: Analoge Elektronik und Schaltungstechnik Möglichst viel Spannungen mit AVR messen?


von AVRli (Gast)


Lesenswert?

Hi,

da ich hier immer gut beraten werde möchte ich mal anfragen ob mir
jemad einen Tip geben könnte welchen Chip ich an meinen ATMEL hängen
kann um möglichst viele Spannungen zu messen.

Bis zu max. 8 sollen es schon sein...

Der ATMEL soll diese überwachen...

Ist der MAX186 / Max188 die richtige Wahl?
Der ist nicht gerade billig deshalb frage ich vorher... ;-)
Vielleicht gibt es aber auch noch eine andere Lösung...

Gruß AVRli

von Edi.Edi (Gast)


Lesenswert?

kannst ja mal mit dem CD4051 analog multiplexer / demultiplexer
spielen....gabs schon vor 25 jahren...heute fuer wenige cents.

viel spass
Ed

von Johannes M. Richter (Gast)


Lesenswert?

Haben nicht eh die meisten AVRs einen 8 oder 10-channel ADC? :-?

von Wolle (Gast)


Lesenswert?

Spannungen messen = ADC
Spannungen auf Anwesenheit prüfen = Spannungteiler, mit Dioden
entkoppelt.

von Andi (Gast)


Lesenswert?

Jau, haben die!
Der Tiny26 hat 11 Channels und die ATMega´s haben 6 oder 8 je nach Typ
und Gehäusetyp.
Alle haben eine Auflösung von 10 Bit (0 bis 1023).
Bei mehr als 5V muß ein Spannungsteiler davor und das in der Software
berücksichtigt werden.
Die Übersicht über die Atmel´s findest Du hier:
http://www.atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC

Gruß
Andi

von AVRli (Gast)


Lesenswert?

Hi Leute,

das klingt ja auch sehr gut!
Bringt doch was wenn man vorher fragt... ;-)

Ich würde dann höchst warscheinlich einen ATMEGA8 verwenden.
Kann mir vielleicht noch jemand im Prinzip sagen wie es dann abläuft?

Konfigurire ich den PIN als A/D Wandler und kann dann dierekt die
Spannung in 0-1024 auslesen?

Ich bin erstaunt was die kleinen µC alles können.
Ich habe nur etwas Erfahrung mit dem AT902323 und dem AT902313.
Denke aber der "Umstieg" dürfte nicht allzu schwer werden.

Mit dem STK500 sind die MEGA hoffendlich "spielbar"...

Gruß AVRli

von Andi (Gast)


Lesenswert?

Bevor Du den ADC aktivierst, sollte man vorher die ADC-Pins, die man
verwendet, auf Input ohne Pullup einstellen.
Man kann Zeitgleich immer nur einen Pin messen bzw. ansteuern.
Per Multiplexer, Register ADMUX, schaltest Du die der Reihe nach
durch.
Der ATMega8 im PDIP-Gehäuse hat allerdings nur 6 ADC-Channel, der
ATMega8 im TQFP-Gehäuse hat 8 Channels.
Wenn Du keinen SMD-µC nehmen willst aber 8 Channels, brauchst Du einen
ATMega48/88/16/32 mit 40 Pins.
Der ATtiny26, 20-Polig, hat 11 Channels aber wenn Du 8 davon nimmst,
bleiben nur noch 7 Pins für I/O übrig (Taster, LED´s, Display etc.).

Gruß
Andi

von AVRli (Gast)


Lesenswert?

Hi Andi,

Ok ich danke für die Infos.
Ich habe mir den ATMEGA8 besorgt.
Werde mal morgen versuchen 0..5V einzulesen...
Mal sehen ob ich das packe...

Danke für die Tips.

Achja und 6 Spannungen messen reicht aus... ;-)

Gruß AVRli

von AVRli (Gast)


Lesenswert?

Ich bin erst heute dazu gekommen das mal anzugehen.
"Quälen" werd ich einen ATMEGA8... :-)

Ein 2x16 Zeichen Display hab ich "schon" dran und der Inhalt vom ADC
Register wird auch schon angezeigt...

Zwar "nur" 0000 aber das liegt daran weil ich noch keine Spannung
eingelesen habe.

Ich muss nochmal fragen bevor ich starte.
Ich kann zwar etwas englisch aber das technisch englisch kann sehr
anstrengend sein.
Bitte verschont mich mit RTFM.
Ich habe Seite 192-205 aus der MEGA8 Duko gelesen... :-) nur nicht
100%tig begriffen.

Was hat es mit dem AVCC Pin und dem AREF Pin auf sich?
Muss man da überhaupt eine Spannung anlegen?
Oder nimmt der ATMEL die Versorgungsspannung automatisch wenn da nix
anliegt?

Und wuzu braucht man den "prescaler" ? :-I
Kenne den vom Timer0/Timer1... begreife nur nicht wozu man ihn hier
braucht.

Messen möchte ich 0-5V.

Gruß AVRli...

von Tobi (Gast)


Lesenswert?

avcc ist die versorgungsspannung des adc, musst du anschliessen. aref
ist die referenzspannung. brauchst du nur wenn du nicht die interne
benutzt. zum ausprobieren kannst du aref auch auf vcc legen, aber auf
jeden fall mit 100nf kerko gegen ground. der prescaler legt fest wie
schnell der adc arbeitet. bleib einfach innerhalb des angegebenen
bereichs dann passt das.

von Tobi (Gast)


Lesenswert?

noch was, die interne ref ist ja 2.65, da bräuchtest du für 5v natürlich
einen spannungsteiler

von AVRli (Gast)


Lesenswert?

Danke Tobi !
Ich werde erstmal "spielen" gehen... :-)

von AVRli (Gast)


Lesenswert?

Tcha so schnell spielt sich es doch nicht... :-I
Ich würde gerne die Spannung an AREF und AVCC über die Pinout Leiste
des STK500 anstecken.

Und nun kommt's... wohin? ;-I
Im Handbuch vom STK-500 gibt es an CONECTOR-0 ein PIN 14  mit "REF".
Ist das AREF?
Wo ist AVCC versteckt...?

Wie bekommt man das nun wieder raus... will doch nix kaputt machen...
;-(

Gruß AVRli...

von AVRli (Gast)


Lesenswert?

Kontaktfrage geklärt...
VREF bekommt man wenn man den REF Jumper auf dem Board STK500 steckt.
AVCC hat 5V...

Spielen tut's noch nicht... es wird aber hoffe ich...

Gruß AVRli

von Tobi (Gast)


Lesenswert?

im user guide steht auf der seite zu den einzelnen ports was die
abkürzungen bedeuten  (s.3-4)

von AVRli (Gast)


Lesenswert?

Hi Tobi,

alles bestens !!! ;-)
0-5V nach 0-1024 nun spring ich hier im Dreieck und freu mich! ;-)
Danke für die Hilfe.

Gruß AVRli

von Thomas O. (Gast)


Lesenswert?

Hallo,

@AVRli : Könntest du mir verraten wie du die Zahlen umwandelt um sie
ans LCD zu schicken?

von AVRli (Gast)


Lesenswert?

@Thomas O.
Hi also ich habe mir so geholfen... ;-)

vorher...
  in ZL,ADCL
  in ZH,ADCH
...dann...
  rcall OUT_REGZ_IN_ASCII:

;*******************************************************************
;* Doppelregister Z in ASCII ausgeben...
;*******************************************************************
OUT_REGZ_IN_ASCII:
;--- 1000er Stelle ---
    clr wrH
SHOW_1000:
  ldi T0,low(1000)
  cp ZL,T0
  ldi T0,high(1000)
  cpc ZH,T0
  brlt OUT_1000

  subi ZL,low(1000)
  sbci ZH,high(1000)
  brmi OUT_1000
  inc wrH
  rjmp SHOW_1000

OUT_1000:
  ldi T0,$30
  add T0,wrH
  rcall TX_LCD_DATA

;--- 100er Stelle ---
  clr wrH
SHOW_100:
  ldi T0,low(100)
  cp ZL,T0
  ldi T0,high(100)
  cpc ZH,T0
  brlt OUT_100

  subi ZL,low(100)
  sbci ZH,high(100)
  brmi OUT_100
  inc wrH
  rjmp SHOW_100

OUT_100:
  ldi T0,$30
  add T0,wrH
  rcall TX_LCD_DATA

;--- 10er Stelle ---
  clr wrH
SHOW_10:
  ldi T0,low(10)
  cp ZL,T0
  ldi T0,high(10)
  cpc ZH,T0
  brlt OUT_10

  subi ZL,low(10)
  sbci ZH,high(10)
  brmi OUT_10
  inc wrH
  rjmp SHOW_10

OUT_10:
  ldi T0,$30
  add T0,wrH
  rcall TX_LCD_DATA

;--- 1er Stelle ---
  ldi T0,$30
  add T0,ZL
  rcall TX_LCD_DATA
  ret

Mit TX_LCD_DATA wird das Byte in T0 zum Display geschikt.

Wenn man das hier noch optimieren kann würde ich mich um einen Beitrag
freuen.

Gruß AVRli

von Tobi (Gast)


Lesenswert?

ich poste mal zwei codeschnipsel die ich hier mal im forum gefunden
habe, beide nicht von mir also bitte nicht fragen wie die funzen oder
warum nicht :) beide ohne lcd ausgabe

*** 1 ***
;*********************************************************************** 
*
;*                  *
;*      binary to bcd conversion      *
;*                  *
;*********************************************************************** 
*
;input: a1, a0 = 16 bit value 0 ... 65535
;output: a4, a3, a2, a1, a0 = digits '0' ... '9'
;cycle: 27 .. 183
;bytes:  42
;
binbcd:
  ldi  a4, -1 + '0'    ;Preload for ASCII output
_bib1:  inc  a4
  subi  a0, low(10000)    ;substract 10000
  sbci  a1, high(10000)
  brcc  _bib1      ;until value negative

  ldi  a3, 10 + '0'
_bib2:  dec  a3
  subi  a0, low(-1000)    ;add 1000
  sbci  a1, high(-1000)
  brcs  _bib2      ;until value positive

  ldi  a2, -1 + '0'
_bib3:  inc  a2
  subi  a0, low(100)    ;substract 100
  sbci  a1, high(100)
  brcc  _bib3      ;until value negative

  ldi  a1, 10 + '0'
_bib4:  dec  a1
  subi  a0, -10      ;add 10
  brcs  _bib4      ;until value positive

  subi  a0, -'0'    ;convert remaining ones to ASCII
  ret
;----------------------------------------------------------------------- 
-
*** 2 ***
;input: ADC result left aligned with AREF set to 5V r16(low byte),
r17(high byte)
;output: Voltage between 0 and 5V at memory location 0x60 to 0x62 =
digits '0' ... '9'
; 21 Words
; CPU cycles: 24



ADCResult2ASCII:
  ldi r25, '0'
  ldi r23, 5
  mul r17, r23
  mov r17, r0
  add r1, r25    ; convert number to ASCII
  sts 0x60, r1
  mul r16, r23
  mov r16, r0
  add r17, r1
  ldi r23, 10

  mul r17, r23
  mov r17, r0
  add r1, r25
  sts 0x61, r1

  mul r17, r23
  add r1, r25
  sts 0x62, r1

  ret

von Thomas O. (Gast)


Lesenswert?

Hallo,

ok danke, werd das mal integrieren, ein LCD bestellen und dann testen.

von AVRli (Gast)


Lesenswert?

Hi,

interessant finde ich den ersten...
Mal ebend mit spielen...

Danke !!!

@Thomas O.
Oass aber auf bei der Bestellung das du eins erwischt wo man den
Kontrast mit 0 bis +5V einstellen kann.
Ich habe den Fehler gemacht und nun 2 hier zu liegen mit -5V und
ohne Beleuchtung. ;-(

Auch auf die Beleuchtung solltest Du achten.
Bei den Preisunterschied würde ich immer eins mit Beleuchtung nehmen.
Nimm lieber LED denn die Leutfolien sollen mit der Zeit nachlassen.

MfG AVRli...

von Andi (Gast)


Lesenswert?

@Tobi:
Danke Tobi für die Code-Schnipsel!
Konnte damit wieder etwas optimieren.
Habe auch eine Routine für die Ziffern von 3 Stellen gemacht. Zwar
nicht zum Anzeigen auf nen Display (nicht vorhanden) aber zum
Auspiepsen.

Bisher so:

ValueBeep:
  ldi  r17,-1
  ldi  r18,-1
ValBeep1:
  inc  r18
  subi  r16,100
  brcc  ValBeep1
  subi  r16,-100
ValBeep2:
  inc  r17
  subi  r16,-10
  brcc  ValBeep2
  subi  r16,-10
        ..........

Jetzt so:

ValueBeep:
  ldi  r17,10
  ldi  r18,-1
ValBeep1:
  inc  r18
  subi  r16,100
  brcc  ValBeep1
ValBeep2:
  dec  r17
  subi  r16,-10
  brcs  ValBeep2
        ..........
Einfach raffiniert jede 2. Stelle nicht raufzuzählen sondern ab einem
Wert von 10 runter bis das Carry-Bit nicht mehr gesetzt ist.
Da spart man sich die Korrektur mit subi r16,-100 und subi r16,-10

Gruß
Andi

von AVRli (Gast)


Lesenswert?

Hi,

auch ich habe mal die Doppel-Registr-Ausgabe auf ein Display
optimiert...
Finde die Lösung mit dem auf und ab zählen ja total genial.
Da muss man ersteinmal drauf kommen !!! ;-)

Viel Spaß... AVRli

;*******************************************************************
;* Doppelregister Z in ASCII ausgeben...                           *
;*******************************************************************
OUT_REGZ_IN_ASCII:
    ldi  T0, -1 + '0'    ;Preload for ASCII output
_bib1:
  inc  T0
    subi  ZL, low(10000)    ;substract 10000
    sbci  ZH, high(10000)
   brcc  _bib1      ;until value negative
;  rcall TX_LCD_DATA ;die erste Stelle nicht ausgeben...

  ldi  T0, 10 + '0'
_bib2:
  dec  T0
  subi ZL, low(-1000)    ;add 1000
  sbci ZH, high(-1000)
  brcs _bib2      ;until value positive
  rcall TX_LCD_DATA

  ldi T0, -1 + '0'
_bib3:
  inc T0
    subi ZL, low(100)    ;substract 100
    sbci ZH, high(100)
    brcc _bib3      ;until value negative
  rcall TX_LCD_DATA

  ldi T0, 10 + '0'
_bib4:
  dec T0
    subi ZL, -10      ;add 10
    brcs _bib4      ;until value positive
  rcall TX_LCD_DATA

  mov T0,ZL
    subi  T0, -'0'    ;convert remaining ones to ASCII
  rcall TX_LCD_DATA
    ret

von Thomas O. (Gast)


Lesenswert?

Hallo,

haben ja jetzt genug Beispiele. Kann mir das bitte jemand erklären wies
funktioniert? Also wie aus z.b. 255 die letzte 5 für eine 7 Segment LED
extrahiert wird?

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.