Forum: Mikrocontroller und Digitale Elektronik Arduino IDE mit Atmega32 - AD Wandler sind nicht benutzbar


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

da ich den Atmega32 in einem Design habe und die Vorzüge der Ard. Libs 
nutzen wollte für Grafikdisplay und RTC Clock habe ich die Hardware Lib 
in die IDE eingebunden und die boards.txt abgeändert. Ebenso die Pin 
Defintion.

Soweit klappt alles, aber es gibt keine A0,A1 Ports usw. Denn diese sind 
nicht im Pinlayout definiert.  Testweise ein

const int A0 = 33


nutzt auch nichts. Die Funktion readAnalog(....) liefert nur einen 
Nonens Wert zurück. readAnalog(30) klappt auch nicht, also wenn man den 
Digitalpin einfach eingibt. Der Wert der zurück kommt ist 280. Irgendwas 
eben.

Eine email an den Autor wurde nicht beantwortet, ist aber üblich, wenn 
man Code Erzeuger anschreibt, dass die nicht reagieren.

Hat jemand dieses Problem schon gelöst?

von avr (Gast)


Lesenswert?

Christian J. schrieb:
> readAnalog(30) klappt auch nicht, also wenn man den
> Digitalpin einfach eingibt. Der Wert der zurück kommt ist 280. Irgendwas
> eben.

Warum soll das denn falsch sein? Irgendwas ist bei einem floatenden Pin 
normal.

von Bernhard F. (bernhard_fr)


Angehängte Dateien:

Lesenswert?

Was macht man so als Profiduino-User so wenn einem am Wochenende 
langweilig ist?
Man geht ins uC-Forum und stellt naiv grenzwertige Fragen und hofft, 
dass die ganzen Arduino-Hater und Assembler-Götter darauf anspringen und 
lehnt sich zurück. Und bei mir Volldepp hat es natürlich auch noch 
funktioniert... und das obwohl ich von Arduino NULL Ahnung habe... aber 
diese verflixte Neugierde, wenn es darum geht zu sehen wie da ein paar 
ATmegas gequält werden...

Du schreibst von einer "readAnalog"-Funktion. Gut will ich jetzt nicht 
drauf rumreiten aber Google fördert dazu nur eine "AnalogRead()" zu 
Tage.
Nach Lektüre von:
http://arduino.cc/en/pmwiki.php?n=Reference/AnalogRead
komme ich schon mal zu dem Schluss, dass die AnalogRead() ganz gerne mit 
einem Wert zwischen 0 und 15 bzw. 0 und 7 beim Mega32 gefüttert werden 
will.

Das es mit dem Digital-Pin-Wert 30 also nicht klappen kann versteht sich 
von selbst...

Grundsätzlich weiß man ja, dass ein einfaches Analog lesen ja auch 
bedeutet, dass im Hintergrund der A/DC bedient wird. Warum sollte das 
dann bei einem als digital definierten Pin klappen? Auf die schnelle hab 
ich leider nicht gefunden, wie genau diese AnalogRead implementiert ist. 
Aber im Zweifelsfall hat der Übergabeparameter was mit dem MUX-Wert in 
den ADC Registern zu tun.

Da mich gerade aber der Geist des Arduino gepackt hat tue ich genau das 
was es ausmacht. Ahnungslos googlen und schauen was am besten passt.
Du schreibst selber, dass A0,A1 usw. im Pinlayout nicht definiert sind 
...
was spricht dagegen das selber zu tun?
Mit nur einem Hauch von logischen Abstraktionsvermögen bin ich noch in 
der Lage nachdem ich deine .h gelesen habe "const uint8_t PROGMEM 
analog" in Google zu füttern.

Erster Treffer ist eine "pins_arduino.h" eines ATmega23u4:
http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCEQFjAA&url=http%3A%2F%2Flearn.adafruit.com%2Fsystem%2Fassets%2Fassets%2F000%2F009%2F337%2Foriginal%2Fpins_arduino.h&ei=cgwWVJXBMITCPKOOgOgD&usg=AFQjCNE34sFFXHt2nIE6tAOOQFtgpMfB7Q&bvm=bv.75097201,d.ZWU&cad=rja
darin finden sich folgende Zeilen:
1
const uint8_t PROGMEM analog_pin_to_channel_PGM[12] = {
2
  7,   // A0          PF7          ADC7
3
  6,   // A1          PF6          ADC6  
4
  5,   // A2          PF5          ADC5  
5
  4,   // A3          PF4          ADC4
6
  1,   // A4          PF1          ADC1  
7
  0,   // A5          PF0          ADC0  
8
  8,   // A6    D4    PD4          ADC8
9
  10,  // A7    D6    PD7          ADC10
10
  11,  // A8    D8    PB4          ADC11
11
  12,  // A9    D9    PB5          ADC12
12
  13,  // A10   D10   PB6          ADC13
13
  9    // A11   D12   PD6          ADC9
14
};

Oh Wunder, das deckt sich ja hervorragend mit dem Datenblatt, dessen 
Ausschnitt ich gleich mal angehangen hab.

Und wenn man sich jetzt noch die Belegung beim z.B. dem Mega2560 oder 
deinem Mega32 anschaut, fällt auf:
ADC0 ist AnalogPin 0
ADC1 ist AnalogPin 1
usw...

kann das sein, dass da gar nix definiert werden muss?
Vielleicht wurde es das genau darum auch nicht?

Schon mal mit AnalogRead(0) versucht um ANALOG_PIN 0 zu lesen?
Wäre ja irgendwie nahe liegend?

Und jetzt erzähl mir bitte nicht, dass du mit deinem Wissenstand und 
deiner Arduino-Erfahrung nie auf diese Idee gekommen wärst...

von Christian J. (Gast)


Lesenswert?

Lieber Bernhard,

danke Dir für die Mühe. Ich habe mir diese auch schon gemacht, ich habe 
sogar diesen Abschnitt in die .h reinkopiert. Wenn man AnalogRead(A0) 
nehmen will, meckert er dass A0 nicht definiert ist für DIESEN Keks, ähm 
Atmega32. Für die anderen aber schon.

Die Struktur der Arduino IDE ist so, dass die Hardware der einzelnen AVR 
abstrahiert wurde, d.h. du hast für jeden ein Verzeichnis, in dem die 
Basis Lib Funktionen stehen. Die heissen immer gleich aber sind 
unterschiedlich angepasst. Daher ist die IDE in der Lage für das 
gewählte Board sich den passenden Source rein zu holen. Jedes Projekt 
läuft auf jedem AVR gleich und die Basisfunktionen decken das ab, was 
jeder an Board hat. Hat er keine SPI wird eine Software SPI eingebunden. 
Das ist pfiffig gemacht.

Den Atmega32 aber gibt es nicht, der wurde von irgendeinem User 
angelegt. Vielleicht auch fehlerhaft. Und genau das versuche ich 
rauszufinden warum ein


AnalogRead(A0) oder
AnalogRead(31)

nicht funktioniert.

A0 ist gleich mit D31 = 31 der Arduniobezeichnung für den Digitalpin, es 
ist egal was man da einträgt.

von Bernhard F. (bernhard_fr)


Lesenswert?

Hast du denn schonmal ganz stumpf AnalogRead(0) versucht?
A0 scheint ja nicht für den Digital-Wert 31 zu stehn, sondern einfach 
eine Konstante mit dem Wert 0 zu sein. In der Online Referenz, die ich 
verlinkt habe ist Analog Pin 3 ja auch nur eine 3.

Und wenn die ArduioIDE vernünftig wäre, könnte ich mir auch mit 2 clicks 
anzeigen lassen, dass das so ist -.-'
Wie ich das rechtsclick "goto implementation" vermisse.

O.K. Nachtrag: Ich habe mir beim Mega2560 mal A0 mit println ausgeben 
lassen... das ergab eine 56. Da ich mir das absolut nicht erklären kann 
(ein digital PIN 56 ist nirgendwo vermerkt) bin ich raus... und bleibe 
bei richtigem C...
Meine Bewunderung gilt allen denen, die überhaupt irgendwas mit dem Kram 
zu Stande bekommen ^^

: Bearbeitet durch User
von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Moin.... halb vier aber soll mir egal sein, habe morgen frei.

Hier ist meine pins.h jetzt aber die klappt auch nicht. Es kommt auf A0 
nur Müll raus. Das sind einfach nur Definitionen, mehr nicht.

Testsignal von 3V an Pin 33 des Atmega angschlossen :
PA7 AI0 D24 (ADC7)

AI0 und D24 sind IDE eigene Definitionen

ein digitalRead(24) liest somit den Pin 33 aus. Das "D" wird 
weggelassen.

von Bernhard F. (bernhard_fr)


Angehängte Dateien:

Lesenswert?

Und doch nochmal ...

Endlich hab ich gefunden was ich gesucht habe, und befinde mich wieder 
auf eine Ebene auf der ich weißt wovon ich rede...

Ich hab mal die wiring_analog.c aus dem Arduino Ordner angehangen.

Eins vorweg, dies ist der dritte Post in dem ich dir sagen werde:

AnalogRead(0) und es wird funktionieren. O.K. in diesem Fall dann halt 
für deinen AnalogIN 7 und mit AnalogRead(7) für deinen AnalogIN(0).

Begründung: ganz einfach folgende Funktion steckt ganz unten im Arduino 
Sumpf...
1
int analogRead(uint8_t pin)
2
{
3
  uint8_t low, high;
4
5
#if defined(analogPinToChannel)
6
#if defined(__AVR_ATmega32U4__)
7
  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
8
#endif
9
  pin = analogPinToChannel(pin);
10
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
11
  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
12
#elif defined(__AVR_ATmega32U4__)
13
  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
14
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
15
  if (pin >= 24) pin -= 24; // allow for channel or pin numbers
16
#else
17
  if (pin >= 14) pin -= 14; // allow for channel or pin numbers
18
#endif
19
20
#if defined(ADCSRB) && defined(MUX5)
21
  // the MUX5 bit of ADCSRB selects whether we're reading from channels
22
  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
23
  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
24
#endif
25
  
26
  // set the analog reference (high two bits of ADMUX) and select the
27
  // channel (low 4 bits).  this also sets ADLAR (left-adjust result)
28
  // to 0 (the default).
29
#if defined(ADMUX)
30
  ADMUX = (analog_reference << 6) | (pin & 0x07);
31
#endif
32
33
  // without a delay, we seem to read from the wrong channel
34
  //delay(1);
35
36
#if defined(ADCSRA) && defined(ADCL)
37
  // start the conversion
38
  sbi(ADCSRA, ADSC);
39
40
  // ADSC is cleared when the conversion finishes
41
  while (bit_is_set(ADCSRA, ADSC));
42
43
  // we have to read ADCL first; doing so locks both ADCL
44
  // and ADCH until ADCH is read.  reading ADCL second would
45
  // cause the results of each conversion to be discarded,
46
  // as ADCL and ADCH would be locked when it completed.
47
  low  = ADCL;
48
  high = ADCH;
49
#else
50
  // we dont have an ADC, return 0
51
  low  = 0;
52
  high = 0;
53
#endif
54
55
  // combine the two bytes
56
  return (high << 8) | low;
57
}

ganz wichtig daraus ist die Zeile:
1
#if defined(ADMUX)
2
  ADMUX = (analog_reference << 6) | (pin & 0x07);
3
#endif
pin ist dann ein Wert zwischen 0 und 7 und der wird binär an die letzten 
4 Positionen des MUX Registers geschrieben bzw wenn es mehr als 8 
Channel sind wird noch mit
1
#if defined(ADCSRB) && defined(MUX5)
2
  // the MUX5 bit of ADCSRB selects whether we're reading from channels
3
  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
4
  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
5
#endif
das MUX5 bit gesetzt...

Die Pointe daran ist, wenn ich mir deine Pin-Definitionen so anschaue:

|40  PA0 AI7 D31 (ADC0)
|39  PA1 AI6 D30 (ADC1)
|38  PA2 AI5 D29 (ADC2)
|37  PA3 AI4 D28 (ADC3)
|36  PA4 AI3 D27 (ADC4)
|35  PA5 AI2 D26 (ADC5)
|34  PA6 AI1 D25 (ADC6)
|33  PA7 AI0 D24 (ADC7)

entspricht anscheinenend dein Analog PIN0 dem ADC7
Auch nicht schlimm... Ich an deiner Stelle würde mir folgende Konstanten 
definieren:

A0 = 7
A1 = 6
.
.
.
A7 = 0

und die ausschließlich für AnalogRead() verwenden.
Sicherlich kann man das auch richtig in das Arduino System einpflegen 
aber das ist mir jetzt wirklich zu blöd...


Und noch einer in eigner Sache.
Nach der Zeile:
1
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
2
  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
bin ich auch schlauer was es mit meiner 56, die ich (bei zugegeben A2 
und nicht A0) vorhin bekommen habe, auf sich hat.
Man oh man ist Arduino kompliziert... mann kann es aber auch echt 
umständlich machen, dass man es leicht hat ;)

von Christian J. (Gast)


Lesenswert?

Ok,

ich schaue es mir morgen an ..... gähn .... Danke für deine Super 
Unterstützng, hast einen gut bei mir!

Das habe ich auch noch gefunden und eingefügt in meine pins.h

#define analogPinToChannel(P)  ( pgm_read_byte( 
analog_pin_to_channel_PGM + (P) ) )

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

PS:

ES KLAPPT  !!!!!!!!!!!!!!!!!!!!
1
// Mapping of analog pins as digital I/O
2
static const uint8_t A0 = 7;
3
static const uint8_t A1 = 6;
4
static const uint8_t A2 = 5;
5
static const uint8_t A3 = 4;
6
static const uint8_t A4 = 3;
7
static const uint8_t A5 = 2;
8
static const uint8_t A6 = 1;  
9
static const uint8_t A7 = 0;

und mit

licht = analogRead(LDR);

Anbei noch die korrigierte pins.h für das Archiv, da die in den Libs 
defintic falsch bzw unvollständig ist.

>>Man oh man ist Arduino kompliziert... mann kann es aber auch echt
>>umständlich machen, dass man es leicht hat ;)

Arduino ist der Name einer Kneipe in Italien.... vielleicht wurde das 
System ja entwickelt nachdem da ordentlich Druckbetankung getätigt 
wurde...

von Bernhard F. (bernhard_fr)


Lesenswert?

Christian J. schrieb:
> PS:
>
> ES KLAPPT  !!!!!!!!!!!!!!!!!!!!

Das ist die Hauptsache, und ob das Ganze jetzt nur ein Quick and Dirty 
Workaround ist, oder sauber eingepflegt, darfst du entscheiden. Den 
Schuh zieh ich mir nicht an.

> Arduino ist der Name einer Kneipe in Italien.... vielleicht wurde das
> System ja entwickelt nachdem da ordentlich Druckbetankung getätigt
> wurde...

Das würde allerdings einiges erklären.

Da kann man schon mal vergessen den ein oder anderen Pin rauszuführen;
Die Brownout Fuse beim Mega2560 mit 16 MHZ auf nur 2,7 Volt stellen;
Ein Rechtecksignal einer Soft-PWM ohne Glättung als Analogwert 
definieren;
Die LED an Pin13 so anbinden, dass sie leuchtet wenn der Pin ein Eingang 
ist und floatet;
Debugmöglichkeiten auf String-Ausgabe beschränken um es "einfacher" zu 
machen;
Das Pinraster der Steckerleisten mit Dartpfeilen festlegen,
und noch viel mehr :D

Aber ich drifte ab...

von c-hater (Gast)


Lesenswert?

Christian J. schrieb:

> Die Struktur der Arduino IDE ist so, dass die Hardware der einzelnen AVR
> abstrahiert wurde, d.h. du hast für jeden ein Verzeichnis, in dem die
> Basis Lib Funktionen stehen. Die heissen immer gleich aber sind
> unterschiedlich angepasst. Daher ist die IDE in der Lage für das
> gewählte Board sich den passenden Source rein zu holen. Jedes Projekt
> läuft auf jedem AVR gleich und die Basisfunktionen decken das ab, was
> jeder an Board hat. Hat er keine SPI wird eine Software SPI eingebunden.
> Das ist pfiffig gemacht.

Nicht wirklich. Es ist ungefähr genauso pfiffig wie die c-lib oder das 
.net-Framework. Es funktioniert unter gewissen Randbedingungen auf 
bestimmten Zielsystemen. (manchmal auch nur mit eingeschränkter 
Funktionalität).

Wer damit nicht leben kann, muß sich selber in die Lage versetzen, bei 
Bedarf die Funktionalität des Frameworks oder die Bandbreite der 
Zielsysteme erweitern zu können. Das geht, indem man die Funktionsweise 
der Frameworks und der Zielsysteme verstehen lernt.

Ohne diese Fähigkeit ist man nur Sklave der Frameworks. Mit dieser ist 
man ein Freier Mensch, denn man hat Entscheidungsspielraum. Entweder man 
entschließt sich, dem Framework die nötigen Fähigkeiten einzuhauchen 
oder man entschließt sich auf das Framework zu verzichten.

Im Bezug auf den Arduino-Dreck fällt die Entscheidung allerdings 
wirklich leicht. Selten wurde ein ineffizienteres und beschränkteres 
Framework mit solch geringer Funktionalität designed.

von stefanus (Gast)


Lesenswert?

Ich habe mit diese Arduino Programmiersoftware vor zwei jahren mal 
angesehen. Nach nur 20 Minuten war klar, dass ich diesen Müll niemals 
benutzen werde. Wenn mein Chef das von mir verlang, kündige ich.

Wie ich immer wieder lese, ist der Müll immer noch Müll - passt zur 
biblischen These, dass Evolution nicht von alleine stattfindet.

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.