Forum: Mikrocontroller und Digitale Elektronik ADC von mehreren Werten


von Hans P. (gableguy2000)


Lesenswert?

Hallo,

ich bin es mal wieder.
Ich würde gerne an dem ADC zwei, später vier Spannungen messen und immer 
zwei vergleichen.
Also
ADC0 mit ADC1
ADC2 mit ADC3

Das soll in einer Schleife passieren, die nur von einem anderen Ausgang 
beendet werden kann.
Erstmal will ich zwei Spannungen messen und abspeichern. Dann die beiden 
Werte voneinander abziehen und eventuell je nachdem was ich raus 
bekomme, einen Ausgang schalten.
Ich habe mir jetzt mal das Prog aus dem Tutorial genommen. Die obige 
Funktion kannich doch so verwenden, oder?
Nur mit dem Aufruf im Main komme ich nicht so klar.
1
void foo(void)
2
{
3
  
4
  uint16_t adcval;
5
 
6
  adcval1 = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
7
  adcval2 = ReadChannel(1); /* MUX-Bits auf 0b0010 -> Channel 1 */
8
  
9
  span = adcval1 - adcval2;
10
  
11
if (....)
12
.
13
.
habe mir das mal zusammengebaut.
Aber ich glaube das es zu einfach ist. Ich habe auch gelesen, das ich 
nach der ersten Messung die Daten verwerfen muss, und nach jeder 
weiteren Messung warten muss bis diese auch wirklich beendet ist.
Aber wo baue ich das ein?Schreibe ich da eine Timer Funktion, die ich 
nach der ersten Messung (Abfrage) aufrufe von 50ms, oder so?
Will auf wissen, ob das Ergebnis von der Subtraktion positiv oder 
negativ ist.
Da kommt bestimmt ieniges auf mich zu, aber wenn ich es für die beiden 
Eingänge hinbekomme, dann ist es ja nur noch copy and paste für die 
anderen beiden Eingänge.

Wäre nett, wenn ich wieder so eine tolle Hilfe wie bei meinen anderen 
Fragen bekommen würde.

Danke

LG

von Timmo H. (masterfx)


Lesenswert?

Prinzipiell ist das so schon vollkommen richtig. Diesen Dummy-Readout 
musst du nur einmal direkt nach dem Aktivieren des ADC machen. Das 
könntest du also z.B. in adc_init() oder so machen.
Oder du lässt es wie im Beispiel in der ReadChannel:
1
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
2
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
3
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
4
  while ( ADCSRA & (1<<ADSC) ) {
5
     ;     // auf Abschluss der Konvertierung warten 
6
  }
7
  result = ADCW;  // ADCW muss einmal gelesen werden,
8
                  // sonst wird Ergebnis der nächsten Wandlung
9
                  // nicht übernommen.

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:

> Aber ich glaube das es zu einfach ist.

Fast.
In deinem Fall musst du adcval als normalen int16_t machen oder 
zumindest bei der Subtraktion entsprechend umcasten. Denn die Differenz 
kann ja auch je nach Spannungen negativ sein. Ein unsigned Wert kann 
aber per Definition nicht negativ sein und auch die Defferenz zweier 
unsigned Werte ist per Definition immer positiv.

> Aber wo baue ich das ein?

Mach dir da mal keine Gedanken drum. Das erledigt die ReadChanel 
Funktion für sich. Die geht auf Nummer sicher. Das ist zwar nicht ganz 
optimal, da hier ein wenig Zeit verschwendet wird (die liegt im Bereich 
von Millisekunden), aber wenn das keine Rolle spielt, brauchst du nichts 
tun.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,


danke für die Antworten.
Also wenn ich adcval geändert habe, dann kann ich mit einer if-Abfrage 
schauen ob das Ergebnis negativ oder positiv ist.
Das kann ich ja dann in einer if Abfrage machen und dort schauen ob die 
Zahl > oder < 0 ist.

Kann ich dann in der main noch eine while Schleife drumbauen, die 
solange aufgerufen iwrd, bis z.B. der Eingang B0 eine 1 hat?
Muss ich keine Timefunktion zwischen die Abfragen machen.
Oder kannich die direkt nacheinander machen?

int16_t adcval1, adcval2, span;

So könnte doch die Zeile in der main aussehen, oder?


Vielen DANK

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

gibt es die Möglichkeit, mir die Daten, die ich vom ADC bekomme irgendwo 
auszugeben?
Bei C++ kann ich mir ja Daten auf der Konsole ausgeben lassen. Da ich 
aber keinen MAX232 habe, den ich mir in die Schaltung bauen kann, ich 
aber gerne wüsste, welche Werte er miteinander vergleicht.
Kann ich irgendwie an mein STK 500 die LDR´s anschließen, und mir dann 
auf der Konsole die Werte ausgeben lassen?

LG

von Karl H. (kbuchegg)


Lesenswert?

Ich denke du solltest dir erst mal das volle Programm geben.
Also: Das Tuorial durcharbeiten.

Bis zu deinen letzten beiden Postings bin ich eigentlich davon 
ausgegangen, dass du programmieren kannst und nur ein paar Ätzes für die 
Spezialitäten und Fallen der µC Programmierung brauchst.

> Kann ich irgendwie an mein STK 500 die LDR´s anschließen

Du schliesst sie genauso an, wie du sie auch an deine tatsächlich 
benutzte µC-Schaltung anschliesst. Wo ist das Problem?

Alternativ, könntest du auch die Tx/Rx Leitungen von deiner 
tatsächlichen Schaltung direkt am dort vorhandenen µC abgreifen (so der 
µC eine UART hat) und über den Umweg STK-500 an den PC durchschleifen 
(das STK-500 'leiht' dir seinen MAX232 (der ein MAX202 ist aber dasselbe 
macht))

Aber lern erst mal mit dem STK-500 wie man eine UART programmiert. Sonst 
führst du einen 2-Frontenkrieg den du nicht gewinnen kannst.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

ich würde die LDR´s ja gerne anschließen, aber meinen mC auch noch im 
Sockel habe, so das er mit dem aufgespielten Prog und den LDR´s mir die 
digitalen Werte auf dem Terminal ausgibt.
Oder soll ich mir lieber einen MAX232 kaufen, serielle Buchse habe ich, 
die ich dann mit dem seriellen Kabel verbinden könnte.

LG

von Karl H. (kbuchegg)


Lesenswert?

Und was hindert dich, dir die fehlende Hardware beim STK "auszuborgen" 
und ein paar Drahtstrippen von der mc-Platine zum STK zu ziehen?
Am STK kommt man sehr einfach an den RS-232 Pegelwandler ran. Da gibt es 
eine 2-polige Stiftleiste die mit Tx/Rx beschriftet ist und direkt zum 
Pegelwandler geht.

von Hans P. (gableguy2000)


Lesenswert?

Hallo Karl heinz,

dann bekomme ich aber doch nur einen Wert angezeigt, muss ja dann auf 
den Rx Pin gehen.
Aber wenn ich mir beide Werte von beiden LDR´s angezeigen lassen will?

Aber Danke, darauf bin ich irgendwie nicht gekommen.

LG

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:
> Hallo Karl heinz,
>
> dann bekomme ich aber doch nur einen Wert angezeigt, muss ja dann auf
> den Rx Pin gehen.
> Aber wenn ich mir beide Werte von beiden LDR´s angezeigen lassen will?

Dann gibst du eben beide aus. Wo ist das Problem?

Du gibst TEXT aus.
Was der Text alles umfasst ist dein Bier!
Und wenn du ans Terminal den Text "SChwupdiwup" schickst, dann zeigt es 
eben "SChwupdiwup" an.

von Hans P. (gableguy2000)


Lesenswert?

O.K.

mC auf STK-500 programmieren, dann auf ein Steckbrett damit.
Vcc und GND anschliessen, 5V an AVCC und REF (wegen der externen 
Ref-Spannung) und dann?

Frage1: meine Ausgänge sind PB0 und PB1, meine Eingänge sind ADC0 und 
ADC1, da hänge ich meine LDR´s dran.
Gehe ich dann von dem TXD PIn des mC, an den RXD Pin auf dem STK 500?
Wie bekomme ich es hin, das beide Werte ausgegeben werden, muss ich da 
ein Prog noch verändern?
Speichere beide Werte in Variablen ab.

Sorry, stehe wieder auf dem Schlauch, bitt nicht sauer werden.
LG

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:

> Frage1: meine Ausgänge sind PB0 und PB1, meine Eingänge sind ADC0 und
> ADC1, da hänge ich meine LDR´s dran.

Mir schwant übles.
Wie hängst du deine LDR an?

Den LDR einfach so an den Pin anhängen geht nicht.
Du musst einen Spannungsteiler aus dem LDR und einem zusätzlichen 
Widerstand aufbauen und den Kreuzungspunkt der beiden mit dem ADC 
Eingang verbinden.

> Gehe ich dann von dem TXD PIn des mC, an den RXD Pin auf dem STK 500?

Nein.
Meines Wissens sind die Pins an dieser Stiftleiste aus Sicht des 
Prozessors beschriftet. Also Tx vom Prozessor kommt an den Tx Pin.

(Daher auch der Vorschlag weiter oben, die UART erst mal mit einem 
Prozessor im STK in Betrieb zu nehmen. Da könnte man sich dann nämlich 
mal ansehen wie das alles eigentlich auf dem STK funktioniert)

> Sorry, stehe wieder auf dem Schlauch, bitt nicht sauer werden.

Du stehts nicht auf dem Schlauch.
Dir fehlt Vieles!
Eigne dir das fehlende Wissen an, indem du das Tut durcharbeitest. Dort 
gibt es auch ein Kapitel darüber, wie man mit dem UART umgeht.
Übe das, indem du möglichst viele Fehlerquellen während des Übens 
ausschliessen kannst.
Das bedeutet: Nicht eine eigene Hardware nehmen, sondern das STK-500, 
denn dort funktioniert die Hardware. Der Prozessor sitzt während der 
ersten Tests nicht in deiner eigenen Platine sondern im STK. Denn dann 
kannst du das STK laut STK-Beschreibung verdrahten und zumindest die 
Hardware stimmt schon mal.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

Danke schön.
Die LDR´s habe ich nicht so, sondern über einen Spanungsteiler an die 
PINS angelegt.
Habe es auch mal getestet, also wennich beide LDR´s anschliesse an ADC0 
und ADC1, Ausgänge sind PB0 und PB1, über den Code aus dem Tutorial 
frage ich die Eingänge ab, speichere die Werte in Variablen.
Diese Variablen werte ich mit einer if Schleife aus, um meine Ausgänge 
zu schalten, klappt eigentlich gut, aber die Empfindlichkeit, wann die 
LED´s umschalten, und das ich die LDR´s nicht so abgeglichen bekomme, 
das beide LEDßs aus sind, das wird mich wohl noch eine Weile 
beschäftigen.
Aus diesem Grund wollte ich mir mal die Werte ausgeben lassen, um zu 
schauen.


LG

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:

> Aus diesem Grund wollte ich mir mal die Werte ausgeben lassen, um zu
> schauen.

Werte ausgeben lassen ist immer gut.

Daher baue ich mir bei einem neuen Projekt IMMER eine Möglichkeit ein, 
wie ich mir Werte anzeigen lassen kann.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

ich kann aber auch die Spannungen an den Eingängen messen und mir dann 
die Werte umrechnen von Hand.
Aber ich weis nicht, wie ich die Schaltung empfindlicher bekomme?
Wenn beide LDR die gleiche Einstrahlung haben, dann müssen die LED´s 
ausgehen, das funktioniert aber auch nicht.
HAst du da eventuell eine IDEE?

LG

von Karl H. (kbuchegg)


Lesenswert?

Sieh zu dass du die Werte rauskriegst.
(Und wenn du sie binär über eine LED rausblinkst ist das immer noch 
besser als nichts. - war ein Scherz -)

Ohne die Werte zu sehen, ist das alles Stochern im Nebel.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

das soll jetzt nicht doof klingen, aber wäre es nicht einfacher, wennich 
ein Display hätte?
Habe mal in anderen Threads geschaut, es gibt ja Lib hier im Forum.
Oder findest du es eien schlecht Idee?
Wenn, welches Display wäre denn für einen Anfänger am besten geeignet? 
Ich meine vom Controller (HDD44780, LC7981)

Komme mit dem anschließen auf dem STK-500 nicht so klar.
Weis nicht, wie ich eine Verbindung vom TX Pin des mC Sockels zum TX PIN 
des RS232 PINS hinbekommen soll. Kann ja schelcht noch ein Kabel 
irgendwo darein klemmen.



LG

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:
> Hallo,
>
> das soll jetzt nicht doof klingen, aber wäre es nicht einfacher, wennich
> ein Display hätte?

Kannst du auch machen.


> Wenn, welches Display wäre denn für einen Anfänger am besten geeignet?
> Ich meine vom Controller (HDD44780, LC7981)

HDD44780
Nimm dir für den Anfang blos kein graphisches LCD.
Da ist alles 3 Nummern komplizierter.

>
> Komme mit dem anschließen auf dem STK-500 nicht so klar.
> Weis nicht, wie ich eine Verbindung vom TX Pin des mC Sockels zum TX PIN
> des RS232 PINS hinbekommen soll. Kann ja schelcht noch ein Kabel
> irgendwo darein klemmen.

Mc Platine umdrehen.
An den Lötpunkten für den Sockel die Pinnummer abzählen, bis du den Tx 
Pin hast.
Kabel nehmen.
Ein Ende abisolieren und dort anlöten.
Das andere Ende auch abisoliern (länger) und um den Tx Pin am STK-500 
wickeln und so straff ziehen, dass Kontakt hergestellt ist.

Schon hast du eine Verbindung.
Noch die Massen der beiden verbinden. Auf dieselbe Art, musst dir halt 
am STK einen Massepin suchen.

Noch mit dem Ohmmeter schnell kontrollieren, ob auch alle Verbindungen 
Durchgang haben.

Fertig.


Sonderlich viel Phantasie für schnelle, temporäre Problemlösungen hast 
du nicht gerade.

von Hans P. (gableguy2000)


Lesenswert?

Hallo,

nein an Phantasie fehlt es mir.
Habe über ein Klemme, den TXD Pin am STK-500 mit dem TXD Pin vom mC (MC 
steckt auf einemn Steckbrett) verbunden. Dann GND vom STK-500 mit dem 
GND vom Steckbrett verbunden. Dem mC auf dem Steckbrett noch 5V vom 
Steckbrett gegeben (an Vcc), Masse auch angeklemmt, aber am Terminalprog 
tut sich nix, habe auch schon die Baudraten ausprobiert.
Wie oder wo klemme ich jetzt den LDR mit dem Spannungsteiler an, damit 
ich den Wert auf dem Terminalprog ausgegeben bekomme?


LG sorry, würde die Sache ja gerne abkürzen und schrieben das es geht, 
aber so richtig bekomme ich es alleine nicht hin.

von Karl H. (kbuchegg)


Lesenswert?

Hans Peter schrieb:
> Hallo,
>
> nein an Phantasie fehlt es mir.
> Habe über ein Klemme, den TXD Pin am STK-500 mit dem TXD Pin vom mC (MC
> steckt auf einemn Steckbrett) verbunden. Dann GND vom STK-500 mit dem
> GND vom Steckbrett verbunden. Dem mC auf dem Steckbrett noch 5V vom
> Steckbrett gegeben (an Vcc), Masse auch angeklemmt, aber am Terminalprog
> tut sich nix, habe auch schon die Baudraten ausprobiert.
> Wie oder wo klemme ich jetzt den LDR mit dem Spannungsteiler an, damit
> ich den Wert auf dem Terminalprog ausgegeben bekomme?

Ähm.
Du bist dir bewusst, dass das Programm im mC von sich aus auf der 
seriellen Schnittstelle nichts ausgeben wird, wenn DU ES NICHT 
HINEINPROGRAMMIERT HAST.

Warum denkst du rede ich mir weiter oben eigentlich den Mund fusselig, 
dass du erst mal am STK-500 üben sollst?

von Hans P. (gableguy2000)


Lesenswert?

Hallo,


habe jetzt versucht das UART in mein Programm zu bekommen, aber leider 
bekomme ich in AVR Studio 4 immer die Fehlermeldung das ich im 
disconnected mode wäre.
Habe aber eigentlich nix anderes gemacht, wie sonst auch.
Hast du da eine Idee?

von Hans P. (gableguy2000)


Lesenswert?

Das disconnect Problem hat sich erledigt.

Sorry

von Hans P. (gableguy2000)


Lesenswert?

Habew jetzt folgendes Prog aus dem Forum verwendet um mal ein Zeichen 
auszugeben:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/signal.h>
4
#include <stdlib.h>
5
6
  /* USART-Init beim ATmega16 */
7
#ifndef F_CPU
8
#define F_CPU 14745600           /* Oszillator-Frequenz in Hz */
9
#endif
10
11
// Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
12
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
13
14
#define UART_BAUD_RATE 9600
15
16
int main()
17
{
18
19
UCSRB |= (1<<TXEN);      // UART TX einschalten
20
UCSRC |= (3 << UCSZ0);  // Asynchron 8N1
21
UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
22
UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
23
24
while(1);
25
{
26
while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
27
28
    
29
UDR = 'x';
30
31
}
32
33
}
verwende den ATmega32
setze den mC auf das STK-500, schicke das Prog rüber, danach stecke ich 
das RS232 Kabel um und stecke das 2 polige Kabel von den RX/TX Pins an 
die PD0/PD1 Pins.

LG

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.