Arduino analogRead funktioniert nicht mit ATTiny85

Gast #5457977
Lesenswert?

ich dachte, man kann die analoge Spannung, die an einem analogen Eingang 
hängt, bei Arduino einfach so auslesen - geht bei mir aber nicht. Die 
Spannungen, die anliegen, sind so zwischen 1V und 0,5V, aber es blinkt 
immer gleich (4x):
1
#define ANALOG_PIN (A1)
2
#define SWITCH_PIN (1)
3

4
int vcc_int_messen() {
5
  analogReference(DEFAULT);
6
  delay(100);
7
  int aval = analogRead(ANALOG_PIN);
8
  aval = analogRead(ANALOG_PIN);
9
  aval = analogRead(ANALOG_PIN);
10
  return aval;
11
}
12

13
void blinken(int mal,int ms) {
14
  for (int i=0; i < mal; i++){
15
    digitalWrite(SWITCH_PIN, HIGH);  
16
    delay(ms);                       
17
    digitalWrite(SWITCH_PIN, LOW);   
18
    delay(ms);  
19
  }
20
}
21

22
void setup()
23
{
24
  pinMode(SWITCH_PIN,OUTPUT);
25
  digitalWrite(SWITCH_PIN, LOW);    
26

27
  while (true){
28
    int bval = vcc_int_messen;
29
    if (bval<100) {blinken(1,200);} else
30
    if (bval<150) {blinken(2,200);} else
31
    if (bval<200) {blinken(3,200);} else
32
    if (bval<250) {blinken(4,200);} else
33
    if (bval<300) {blinken(5,200);} else
34
    if (bval<350) {blinken(6,200);} else
35
    if (bval<400) {blinken(7,200);} else
36
     {blinken(8,200);}
37
    delay(2000);
38
 }
39
}
40

41
void loop() {
42
}

Woran kann es liegen? Die Spannung liegt an Pin 7 an (kann man mit dem 
Messgerät nachmessen) der Chip läuft mit 5V..
Gast #5457997
Lesenswert?

Dr. Sommer schrieb:
> Und das ist ganz sicher der korrekte kompilierbare Code?

ja.


> Warum setzt du immer wieder die Referenz neu?

Ist übrig aus einem größeren Programm, wo sie verändert wurde. Solle 
nicht schaden..

Warum ist die Schleife in
> setup() und nicht in loop()?

ich glaub das ist in meinem Fall Wurscht.. ist ja nur ein Testprogramm.

> Sicher dass delay() mit variablen Werten korrekt funktioniert?

ja.
Gast #5458000
Lesenswert?

Anna log schrieb:
> ja.

Und wie kann dann ein Funktionspointer ohne Fehler implizit in einen 
Integer konvertiert werden?

Anna log schrieb:
> Ist übrig aus einem größeren Programm, wo sie verändert wurde. Solle
> nicht schaden..

Nach dem Umschalten der Referenz liefert der ADC etwas Müll. Kann sein 
dass du das immer wieder auslöst. Schiebe die eine Zeile doch an den 
Anfang der setup().

Anna log schrieb:
> ich glaub das ist in meinem Fall Wurscht.. ist ja nur ein Testprogramm.

Sicher dass das Auslesen des ADC usw in der setup() klappt und Arduino 
nicht zwischen setup() und loop() nicht noch irgendwas einrichtet?

Carl D. schrieb:
> Nämlich die Adresse der Funktion vcc_int_messen

Ich würde eher auf 1 tippen, weil hier vermutlich erst nach bool 
konvertiert wird.
#5458003
Lesenswert?

Anna log schrieb:
> Dr. Sommer schrieb:
>> Und das ist ganz sicher der korrekte kompilierbare Code?
>
> ja.
Mit einigen Warnungen, die nicht unbedeutend sind.


>> Warum setzt du immer wieder die Referenz neu?
>
> Ist übrig aus einem größeren Programm, wo sie verändert wurde. Solle
> nicht schaden..
Danach braucht der ADC eventuell eine Wandlung, um wieder auf der Spur 
zu sein.

> Warum ist die Schleife in
>> setup() und nicht in loop()?
>
> ich glaub das ist in meinem Fall Wurscht.. ist ja nur ein Testprogramm.
Wurscht schon, aber wenn loop() eh schon da steht, warum nicht gleich 
richtig?

>> Sicher dass delay() mit variablen Werten korrekt funktioniert?
>
> ja.
Nein!
Es macht wohl was, aber sicher nicht ein delay mit dem übergebenen Wert. 
Das geht nur wenn man z.B. delay(1) in einer Schleife aufruft, dann darf 
der Schleifenzähler dynamisch mit den 200 zu wartenden ms gefüllt 
werden.
Gast #5458071
Lesenswert?

irgendwie ist es nicht leicht zu debuggen in der Arduino IDE, wenn man 
nur eine LED als Anzeigen hat.. :-)

Wäre diese Funktion ok, um den Wert als float zu lesen? Schaltung läuft 
auf 5V, A1 misst externe Spannung (12V) angeschlossen über 
Spannungsteiler..
1
#define ANALOG_PIN (A1)
2
#define adc_disable() (ADCSRA &= ~(1<<ADEN))
3
#define adc_enable()  (ADCSRA |= 1<<ADEN)
4

5

6
float vcc_messen() {
7
  adc_enable();
8
  analogReference(DEFAULT);
9
  delay(100);
10

11
  int aval = analogRead(ANALOG_PIN);
12
  // mehrmals weil erste Messung Müll?
13
  aval = analogRead(ANALOG_PIN);
14
  aval = analogRead(ANALOG_PIN);
15
  float rvcc = aval * 5 / 1023 * 12; // Spannungsteiler 1+11 
16
  adc_disable();
17
  return rvcc;
18
}
#5458143
Lesenswert?

Anna log schrieb:
> irgendwie ist es nicht leicht zu debuggen in der Arduino IDE, wenn
> man
> nur eine LED als Anzeigen hat.. :-)
.
> Wäre diese Funktion ok, um den Wert als float zu lesen? Schaltung läuft
> auf 5V, A1 misst externe Spannung (12V) angeschlossen über
> Spannungsteiler..
.
> #define ANALOG_PIN (A1)
> #define adc_disable() (ADCSRA &= ~(1<<ADEN))
> #define adc_enable()  (ADCSRA |= 1<<ADEN)
>
> float vcc_messen() {
>   adc_enable();
>   analogReference(DEFAULT);
>   delay(100);
>
>   int aval = analogRead(ANALOG_PIN);
>   // mehrmals weil erste Messung Müll?
>   aval = analogRead(ANALOG_PIN);
>   aval = analogRead(ANALOG_PIN);
>   float rvcc = aval * 5 / 1023 * 12; // Spannungsteiler 1+11
>   adc_disable();
>   return rvcc;
> }
Warum nicht, die FP-Lib wird in 8k passen.
Nur wird der Ausdruck als int berechnet (da alle Beteiligten int) und 
erst das ganzzahlige Ergebnis nach float konvertiert. Wenn die 
konstanten Werte mit Nachkommastellen da stehen ("x.0"), dann passiert 
das Gewünschte.
Gast #5458199
Lesenswert?

Carl D. schrieb:
> Nur wird der Ausdruck als int berechnet (da alle Beteiligten int) und
> erst das ganzzahlige Ergebnis nach float konvertiert.

Ah.. sollte ich besser schreiben

float rvcc = aval * 5 *12 / 1023;

und außerdem nach long konvertieren? denn int geht ja nur bis 65535.. - 
und wenn aval maximal 1023 ist, dann geht's schon drüber?

Also ich würde gerne alles als Gleitkomma rechnen lassen.. oder 
zumindest in der Reihenfolge wie oben.
#5458249
Lesenswert?

Anna log schrieb:
> Carl D. schrieb:
>> Nur wird der Ausdruck als int berechnet (da alle Beteiligten int) und
>> erst das ganzzahlige Ergebnis nach float konvertiert.
>
> Ah.. sollte ich besser schreiben
>
> float rvcc = aval * 5 *12 / 1023;

Eher so:
1
float rvcc = aval * 5.0 / 1023.0 * 12.0;
Dann berechet der Compiler den konstanten Teil zur Übersetzungszeit und 
generiert eine FP-Multiplikation dieser Konstante mit aval.

> und außerdem nach long konvertieren? denn int geht ja nur bis 65535.. -
> und wenn aval maximal 1023 ist, dann geht's schon drüber?
Wozu, aval kann gleich nach float konvertiert werden.

> Also ich würde gerne alles als Gleitkomma rechnen lassen.. oder
> zumindest in der Reihenfolge wie oben.
Siehe oben
Gast #5458374
Lesenswert?

Anna log schrieb
>Vielen Dank, das war das Problem :-)
>So ein Mist - ich mach nicht so viel mit Arduino, und die Warnungen
>werden bei mir gar nicht ausgegeben..

Gibt's da nicht den Spruch "das Problem sitzt vor dem Arduino" ?
Gast #5458402
Lesenswert?

Arduino Fanboy D. schrieb:
>> float rvcc = aval * 5.0 / 1023.0 * 12.0;
> Auch wenn es nicht viel ausmacht...
> Quasi im Rauschen unter geht...
> Muss es nicht 1024.0 heißen, statt 1023.0?

Mir stellt sich eher die Frage, wie weit die Auflösung verloren geht. 
5/1023 = 0,0048876, da hätte ich doch gerne 5 Nachkommastellen in der 
Berechnung.
Gast #5458459
Lesenswert?

Johannes S. schrieb:
> Werden in der Arduino IDE fp Konstanten als float compiliert?

habe es ausprobiert und kann es mir selber beantworten: das ABI des gcc 
behandelt float und double gleich, es gibt nur 4 Byte floats.
Daher ist es für Arduino Programme mit AVR als MCU egal. Portiert man 
die Programme oder Libs auf einen 32 Bitter ist es ein grosser 
Unterschied ob eine Konstante 10.0 oder 10.0f geschrieben wird.
Gast #5459591
Lesenswert?

Johannes S. schrieb:
> Manfred schrieb:
>> da hätte ich doch gerne 5 Nachkommastellen in der Berechnung.
> Hast du, fp werden intern normiert.

Carl D. schrieb:
> Eher so:float rvcc = aval * 5.0 / 1023.0 * 12.0;

Bei "1023.0" bekomme ich in Arduino einen Wert mit einer Nachkommastelle 
geliefert, mit "1023.00" wären es zwei. Ich habe noch nicht untersuchen 
müssen, was hinter den Kulissen passiert, mit wieviel Auflösung 
tatsächlich gerechnet wird.
#5459620
Lesenswert?

Anna log schrieb:
> ich dachte, man kann die analoge Spannung, die an einem analogen Eingang
> hängt, bei Arduino einfach so auslesen - geht bei mir aber nicht. Die
> Spannungen, die anliegen, sind so zwischen 1V und 0,5V

Anna log schrieb:
> irgendwie ist es nicht leicht zu debuggen in der Arduino IDE, wenn man
> nur eine LED als Anzeigen hat.. :-)

dafür haben die Erfinder doch Serial.print eingebaut

Anna log schrieb:
> float rvcc = aval * 5 *12 / 1023;

warum will man ausgerechne float nutzen?

besser und kleiner gehts doch mit Ganzzahlwerten

ich rechne da immer mV milliVolt oder dV deziVolt

da passen in ein int16_t ohne float Berechnung 65000 mV oder 65000 dV

Bei deinem Bereich sollte das doch völlig ausreichend sein in mV mit 
65000 mV kommst du auf Umax von 65V mit 3 Kommastellen, so genau ist der 
ADC eh nicht und auflösen kann er es auch nicht.

Man kann sogar die ADC Werte aufsummieren und mitteln 8-32 fach (2^n) 
und durch rechtshiften wieder schnell teilen.
Gast #5459622
Lesenswert?

Manfred schrieb:
> Bei "1023.0" bekomme ich in Arduino einen Wert mit einer Nachkommastelle
> geliefert, mit "1023.00" wären es zwei.


https://de.wikipedia.org/wiki/IEEE_754

eine 1023.0 wird intern normalisiert (nicht normiert wie ich geschrieben 
hatte) zu 1,023 E3. Ein single float hat 7-8 signifikante Stellen, 
(fast) egal wie gross der Wert ist. Ein Problem gibts nur wenn man 
grosse und kleine Werte addiert, dann geht die Genauigkeit verloren wenn 
eben diese 7-8 Stellen überschritten werden.

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