Forum: Mikrocontroller und Digitale Elektronik ADC gibt alle X Sekunden einen falschen Wert aus


von Jannis P. (jannis94)


Lesenswert?

Hallo ich habe eine Temperatursteuerung mit dem Adruino Uno realisiert. 
Es funktioniert auch alles so weit ganz gut, nur der ADC gibt alle X 
Sekunden (manchmal 10 dann wieder 15 oder weniger/mehr) einen Wert bei 
950 aus. Bei Zimmertemperatur ist er normalerweise immer so bei 505 = 
22°C ca +/- 1°C.
Der Wert ist dann aber auch sofort wieder weg und passt sich wieder auf 
505 an.
Hab an die anderen zwei ADC-Anschlüsse noch die Tastensteuerung und 
einen Feuchtigkeitssensor angeschlossen. Hier funktioniert alles 
wunderbar. Keine extremen Abweichungen.
Hier der Temperaturprogrammteil aus Bascom:

Temperatur:

Adc_key_in = Getadc(2)

Locate 1 , 1
Lcd "Temp:"
Locate 1 , 8
Lcd "Alarm:"
Locate 1 , 14
Lcd Y
Locate 2 , 1
Lcd "ADC2:" ; Adc_key_in ; "    "
Locate 2 , 10
Lcd "="
Locate 2 , 11
Lcd X
Locate 2 , 14 : Lcd Chr(2)
Deflcdchar 2 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
Locate 2 , 15
Lcd "C"

Do

If A = 0 Then
Y = "Yes"
C = 0
Elseif A = 1 Then
Y = "No "
C = 1
Elseif A = -1 Then
A = 1
Y = "No "
C = 1
Elseif A = 2 Then
A = 0
Y = "Yes"
C = 0
Else
A = A

End If


Bv = Getadc(2)
If Bv > -1 And Bv < 385 Then
X = "low"

Elseif Bv > 384 And Bv < 395 Then
X = "10 "

Elseif Bv > 394 And Bv < 405 Then
X = "11 "

Elseif Bv > 404 And Bv < 415 Then
X = "12 "

Elseif Bv > 414 And Bv < 425 Then
X = "13 "

Elseif Bv > 424 And Bv < 435 Then
X = "14 "

Elseif Bv > 434 And Bv < 445 Then
X = "15 "

Elseif Bv > 444 And Bv < 455 Then
X = "16 "

Elseif Bv > 454 And Bv < 465 Then
X = "17 "

Elseif Bv > 464 And Bv < 475 Then
X = "18 "

Elseif Bv > 474 And Bv < 485 Then
X = "19 "

Elseif Bv > 484 And Bv < 495 Then
X = "20 "

Elseif Bv > 494 And Bv < 505 Then
X = "21 "

Elseif Bv > 504 And Bv < 515 Then
X = "22 "

Elseif Bv > 514 And Bv < 525 Then
X = "23 "

Elseif Bv > 524 And Bv < 535 Then
X = "24 "

Elseif Bv > 534 And Bv < 545 Then
X = "25 "

Elseif Bv > 544 And Bv < 555 Then
X = "26 "

Elseif Bv > 554 And Bv < 565 Then
X = "27 "

Elseif Bv > 564 And Bv < 575 Then
X = "28 "

Elseif Bv > 574 And Bv < 585 Then
X = "29 "

Elseif Bv > 584 And Bv < 595 Then
X = "30 "

Elseif Bv > 594 And Bv < 605 Then
X = "31 "

Elseif Bv > 604 And Bv < 615 Then
X = "32 "

Elseif Bv > 614 And Bv < 625 Then
X = "33 "

Elseif Bv > 624 And Bv < 635 Then
X = "34 "

Elseif Bv > 634 And Bv < 645 Then
X = "35 "

Elseif Bv > 644 And Bv < 655 Then
X = "36 "

Elseif Bv > 654 And Bv < 665 Then
X = "37 "

Elseif Bv > 664 And Bv < 675 Then
X = "38 "

Elseif Bv > 674 And Bv < 685 Then
X = "39 "

Elseif Bv > 684 And Bv < 695 Then
X = "40 "

Elseif Bv > 694 And Bv < 1024 Then
X = "up "

Else
Waitms 1000
Goto Timer_isr6

End If
Waitms 1000
Locate 2 , 6
Lcd "    "
Locate 2 , 11
Lcd "   "
Locate 2 , 16
Lcd " "
Goto Timer_isr6
Loop
End

-----------------------------------------
Vielen Dank für eure Hilfe.
Mfg Jannis

: Bearbeitet durch User
von Thomas (Gast)


Lesenswert?

Schau dir dringend mal den Befehl "select case" an.

von decimad (Gast)


Lesenswert?

Problembezogen habe ich keine Ahnung, aber kam Dir beim Tippen des 5. 
elseif nicht irgendwann der Gedanke, dass es doch auch irgendwie anders 
gehen muss?

von Thomas (Gast)


Lesenswert?

Und was soll das "Goto Timer_isr6"? Poste mal das ganze Programm.

von decimad (Gast)


Lesenswert?

Irgendwie (Bv-385)/10 und das Ergebnis in einen String umwandeln (-> 
irgendwie mod in ein array von chars)? wenn ich das Basic da richtig 
intepretiere.

von decimad (Gast)


Lesenswert?

-285 muss das natürlich sein, Du fängst ja bei "10" an, hab ich nicht 
bedacht.
Und das Array war auch blöd, das ist ja bestimmt Ascii/Ansi-Kodierung, 
also einfach '0'+Stelle, falls das in Basic geht.

von Jannis P. (jannis94)


Lesenswert?

Mit SelectCase wird es auch nicht wirklich kürzer.
Do

Temperatur = Getadc(2)
         Locate 2 , 9
         Fall


         Waitms 10
Loop
End


Sub Fall
Select Case Temperatur
Case 515 To 556
Lcd " 20 "
Case 515 To 525
Lcd " 21 "
Case 525 To 535
Lcd " 22 "
Case 535 To 545
Lcd " 23 "
Case 545 To 556
Lcd " 24 "

End Select

End Sub
------------------------
Außerdem geht es mir ja nicht darum das Programm zu kürzen( zumindest 
noch nicht), sondern den Fehler ausfindig zu machen. Aber trotzdem schon 
einmal danke für Tipps, die später das Programm besser aussehen lassen.

von Thomas (Gast)


Lesenswert?

Jannis P. schrieb:
> Hab an die anderen zwei ADC-Anschlüsse noch die Tastensteuerung und
> einen Feuchtigkeitssensor angeschlossen.

Das Problem könnte ja auch damit zusammenhängen und nicht zwingend mit 
dem gepostetem Programmteil.

von Jannis P. (jannis94)


Lesenswert?

Thomas schrieb:
> Jannis P. schrieb:
>> Hab an die anderen zwei ADC-Anschlüsse noch die Tastensteuerung und
>> einen Feuchtigkeitssensor angeschlossen.
>
> Das Problem könnte ja auch damit zusammenhängen und nicht zwingend mit
> dem gepostetem Programmteil.
Also hab jetzt mal die Zeit gestoppt, es ist immer in der 27 Sekunde, wo 
die ADC Zahl auf 948 geht schon in der nächsten Sekunde sind es wieder 
515. Ich hab nirgendwo 27 Sekunden verwendet oder nur in der Nähe davon. 
Außerdem dürften die anderen Adc-Eingänge, diesen doch nicht stören 
oder?

von decimad (Gast)


Lesenswert?

Was läuft denn da sonst noch so? Gibts vielleicht irgendwelche 
Konflikte, weil in der 27. Sekunde mehrere getimete Dinge 
zusammenlaufen?
Kann der "inport" eigentlich überhaupt durch Interrupts unterbrochen 
werden?

von Jannis P. (jannis94)


Lesenswert?

Ich hab die Tastersteuerung im Hintergrund laufen, die ein in das 
Hauptmenü zurück bringt, dann kann man im Temperaturfenster noch den 
Alarm aus und anschalten und es läuft im Hintergrund noch die Uhrzeit, 
welche jede Sekunde durchläuft und die Sicherheitsüberprüfung, ob die 
Bodenfeuchte einen kritischen Wert erreicht. Dann fängt eine LED an zu 
blinken. Das ist eigentlich alles was im Hintergrund läuft. Hab das 
Temperaturprogramm schon mal ausgegliedert und der Fehler ist weg, ist 
also nur im Zusammenhang mit dem ganzen Programm. Das Programm ist aber 
ziemlich groß, wenn ich das hier posten würde.
Danke für eure Hilfe.

von decimad (Gast)


Lesenswert?

Einer der Profis hier könnte Dir bestimmt helfen, wenn Du ein minimales 
Codebeispiel beibringst, das das Problem gerade noch enthält.

von Jannis P. (jannis94)


Lesenswert?

Hab jetzt zu dem abgesonderten Teil Temperaturanzeige den ich erstellt 
habe den TImer sinnlos hinzugepackt und es kommt wieder der Fehler. Aber 
es ist immer unterschiedlich.
-------------------------
Timer_isruhrzeit:                                           'Hier wird 
dafür gesorgt, dass die Uhrzeit immer möglichst konstant im Hintergrund 
weiterläuft oder im Uhrenanzeigeprogramm angezeigt wird

Timer1 = 3036

If Hss < 9 Then
 Hss = Hss + 1

Elseif Hss = 9 And Hs < 5 Then
 Hss = 0
 Hs = Hs + 1

Elseif Hs = 5 And Hss = 9 And Hmm < 9 Then
 Hs = 0
 Hss = 0
 Hmm = Hmm + 1

Elseif Hmm = 9 And Hs = 5 And Hss = 9 And Hm < 5 Then
 Hm = Hm + 1
 Hmm = 0
 Hs = 0
 Hss = 0

Elseif Hm = 5 And Hmm = 9 And Hs = 5 And Hss = 9 And Huu < 9 And Hu < 2 
Then
 Huu = Huu + 1
 Hm = 0
 Hmm = 0
 Hs = 0
 Hss = 0

Elseif Huu = 9 And Hm = 5 And Hmm = 9 And Hs = 5 And Hss = 9 And Hu < 2 
Then
 Hu = Hu + 1
 Huu = 0
 Hm = 0
 Hmm = 0
 Hs = 0
 Hss = 0

Elseif Hu = 2 And Huu < 3 And Hm = 5 And Hmm = 9 And Hs = 5 And Hss = 9 
Then
 Huu = Huu + 1
 Hm = 0
 Hmm = 0
 Hs = 0
 Hss = 0

Elseif Hu = 2 And Huu = 3 And Hm = 5 And Hmm = 9 And Hs = 5 And Hss = 9 
Then
 Hu = 0
 Huu = 0
 Hm = 0
 Hmm = 0
 Hs = 0
 Hss = 0

End If
'#####Teil2#####        'Dies ist die Tastersteuerung für den 
Programmunterpunkt Bodenfeuchte
If Ue = 1 Then

 Adceingang = Getadc(0)

 If Adceingang > 1000 Then                                  'Kein Taster
  H = H

 Elseif Adceingang < 50 Then                                'Taster 
rechts
  H = H

 Elseif Adceingang < 195 Then                               'Taster oben
  Locate 2 , 16 : Lcd Chr(1)
  Deflcdchar 1 , 4 , 14 , 31 , 14 , 14 , 14 , 14 , 14
  H = H + 1
  Www = Www + 1
  Locate 1 , 1
  Lcd "                "
  Locate 2 , 1
  Lcd "               "

 Elseif Adceingang < 380 Then                               'Taster 
unten
  Locate 2 , 16 : Lcd Chr(2)
  Deflcdchar 2 , 14 , 14 , 14 , 14 , 14 , 31 , 14 , 4
  H = H - 1
  Www = Www + 1
  Locate 1 , 1
  Lcd "                "
  Locate 2 , 1
  Lcd "               "

 Elseif Adceingang < 555 Then                               'Taster 
links
  H = H

 Elseif Adceingang < 790 Then                               'Taster 
select
  Ue = Ue + 3
  Locate 2 , 16 : Lcd Chr(3)
  Deflcdchar 3 , 4 , 8 , 14 , 9 , 5 , 17 , 14 , 32

End If
Goto Sonstiges

Sonstiges:

Else
 Ue = Ue

End If
'########################Teil3-Alarm##########
Adc_key_in = Getadc(1)                                      'steuert den 
Alarm

If Adc_key_in < 381 And C = 0 And Al = 0 Then
 Set Portd.2
 Al = 1

Elseif Adc_key_in < 381 And C = 0 And Al = 1 Then
 Reset Portd.2
 Al = 0

Elseif Adc_key_in < 381 And C = 1 Then
 Reset Portd.2

Else
Reset Portd.2

End If

Al = Al

'##########Teil4-Aktualisierung/Uhrzeit-Feuchtigkeit#######
                                                     'sorgt dafür, dass 
die Bodenfeuchtigkeit im Uhrzeit-Menü mit einer gewissen Verzögerung 
aktualisiert wird

We = We + 1

If We = 3 Then
We = 0

Else
We = We


End If

Return

von decimad (Gast)


Lesenswert?

Minimalbeispiel meint vor allem, dass man allen Code entfernt, der nicht 
zum Nachvollziehen des eigentlichen Problems nötig ist. Tritt das 
Problem auch auf, wenn Du die Werte nicht in den ellenlangen 
if-else-Blöcken weiterverarbeitest? Dann gehören die auch 
rausgeschmissen.
Und das dann als Codedatei anhängen, sodass man es sich in einem 
vernünftigen Editor anschauen kann.
So kann etwas minimales die Chancen für Hilfe maximieren ;)

Aber es kristallisiert sich heraus, dass es hier um die Interaktion 
irgendeines unzusammenhängenden Timers mit dem Auslesen des AD-Wandlers 
geht, oder?

von Jannis P. (jannis94)


Lesenswert?

decimad schrieb:
> Minimalbeispiel meint vor allem, dass man allen Code entfernt, der nicht
> zum Nachvollziehen des eigentlichen Problems nötig ist. Tritt das
> Problem auch auf, wenn Du die Werte nicht in den ellenlangen
> if-else-Blöcken weiterverarbeitest? Dann gehören die auch
> rausgeschmissen.
> Und das dann als Codedatei anhängen, sodass man es sich in einem
> vernünftigen Editor anschauen kann.
> So kann etwas minimales die Chancen für Hilfe maximieren ;)
>
> Aber es kristallisiert sich heraus, dass es hier um die Interaktion
> irgendeines unzusammenhängenden Timers mit dem Auslesen des AD-Wandlers
> geht, oder?

Jop es ist auch so. Habe das Problem gelöst :D
Das Problem war wieder einmal meine Dämlichkeit. Ich habe im Timer bei 
der Alarm Abfrage geschrieben:
Adc_key_in = Getadc(1)
und im Temperaturprogramm zum Auslesen von ADC(2):
Adc_key_in = Getadc(2)


Locate 2 , 1
Lcd "ADC2:" ; Adc_key_in ; "    "
---------------------------------------
Die Frage ist nur, warum tritt dieser Fehler nur alle 27 Sekunden auf.
Die Temperaturschleife läuft mit 1000ms
Die Timerschleife läuft mit 3036ms

9*3036 = 27324/1000 = 27,324 Sekunden :O

Wie auch immer.
Danke für Eure Hilfe.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Jannis P. schrieb:
> Mit SelectCase wird es auch nicht wirklich kürzer.

Es würde kürzer werden, wenn du einfach mal ein bischen rechnen würdest!

deine Temperaturen ergeben sich durch

  Temperatur = ( ADC_Wert - 385 ) / 10 + 10


eine Zeile (bzw für BASCOM aufgedröselt in 3 zeilen) anstatt 2 Seiten if 
- else if oder switch case

> Außerdem geht es mir ja nicht darum das Programm zu kürzen( zumindest
> noch nicht), sondern den Fehler ausfindig zu machen.

schlecht zu findende Fehler haben oft damit zu tun, dass man den 
Überblick verloren hat. Und das hängt wiederrum oft damit zusammen, dass 
man die Dinge komplizierter macht als notwendig.


Du gibst in einer ISR und im Hauptprogramm auf das LCD aus? Das nenn ich 
mutig.

: Bearbeitet durch User
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.