Hallo,
ich möchte einen Soil Moisture Sensor (Sensor:YL-69, Modul YL-38) an
meinen ATTiny13 schließen. Sensor hab ich bereits mit dem UNO getestet
und dieser funktioniert einwandfrei. Danach hab ich den Uno als ISP
Programmer verwendet, um Code auf den ATTiny zu spielen. Ziel ist es
derzeit eigentlich nur den Sensor über ADC2 (=PB4) einzulesen und damit
eine LED bei einem Treshhold an PB3 einzuschalten. Soweit so gut. Das
Programm funktioniert mit einem Poti wie gewünscht.
Das Problem ist, egal wie ich den Wertebereich einschränke, die LED
schaltet nie um, wenn der Sensor angesteckt ist.
Schaltung:
UNO mit ATTiny für ISP
Wassersensor: Vcc/GND/ADC2->AO
LED: PB3 -> 200Ohm -> LED -> GND
if(channel>3)return0;// Catch channel numbers greater than 3, because there not more than 2 bits to choose the ADC
12
ADMUX|=(1<<REFS0)+channel;// select ADC channel (here: channel 3) for next conversion
13
ADCSRA|=(1<<ADSC);// start single conversion: Start the ADC
14
while(ADCSRA&(1<<ADSC));// wait until conversion is finished (see data sheet page 92)
15
uint16_tresult=ADCL;// store low byte of sample value in variable
16
result+=(ADCH<<8);// add high byte of sample value
17
returnresult;
18
}
19
20
intmain(void){
21
DDRB|=(1<<3);
22
adc_init();
23
while(1){
24
uint16_tval=adc_read(2);
25
if(val>512){
26
PORTB|=(1<<3);//If ADC value is above 512 turn led on
27
}else{
28
PORTB&=~(1<<3);
29
}
30
}
31
}
Des weiteren: Derzeit läuft der Controller auf den 5V vom Uno. Ist aber
geplant ihn auf 3V Knopfzelle umzustellen. Derzeit wird ja mit ADMUX |=
(1<<REFS0) gesagt, dass die interne 1,1V Referenspannung als Vergleich
dient. Ich versteh zwar nicht ganz, wie er daraus dann Werte berechnet,
aber vielleicht kann mir das ja wer erklären. Vcc=5V?!
Vielen lieben Dank im Vorhinein :)
Hi,
ist die LED immer an oder aus?
Hast du die Spannung am ADC-Pin mal mit einem Multimeter gemessen ?
Bei der internen Referenzspannung von 1,1 Volt kannst du halt bis 1,1 V
messen. Alles darüber bleibt 1023.
Gruß JackFrost
Hi,
Also ja, hab ich gemessen. Die LED beim Wassersensor ist immer an. Ich
finds nur interessant, weil ja die Spannung doch auch auf knape 0V
kommt.
Spannung ist beim Wassersensor, wie auch beim Poti zwischen 0 und 4,7V
(bei Vcc 5v) und zwischen 0 und 2,7V (bei Vcc 3V). Eben deswegen ja
meine Frage, wie das skaliert/gemessen wird. Interessant find ich ja
nur, dass beim Poti eigentlich funktioniert.
Wobei: Bei einem Treshold von 500 ist die LED beim Poti bei ~0,5V
angegangen, Bei Treshold 1000, bei ungefähr 1V... Ich seh ja den Fehler
eh schon ungefähr. Es ist die Referenzspannung zu den internen 1,1V. Da
dürfte der Uno wohl zu 5V referenzieren? Das Problem ist: Wenn ich ADMUX
|=
~(1<<REFS0) schreibe, funktioniert garnichts und ich weiß nicht warum.
Jemand eine Idee?
Grüße
Michael D. schrieb:> uint16_t result=ADCL;// store low byte of sample value in variable> result+=(ADCH<<8);// add high byte of sample value
warum so kompliziert?
Peter D. schrieb:> Nur mit ner LED durchs Nadelöhr zu debuggen, ist recht mühsam.> Nimm besser ne UART und gib den ADC als Zahl (itoa) aus:> Beitrag "Re: Kleines Programm für Debug Ausgaben"
Der ATTiny13 hat kein USART soweit ich weiß. Hab quasi das Programm auch
mit dem UNO getestet mittels HTERM. Gibt mir sowohl für den Potti, als
auch für den Wassersensor schöne Werte von 0 bis 1023 aus. Dürfte aber
eben eine andere Referenzspannung sein bei ADMUX |= (1<<REFS0)
MWS schrieb:>
1
ADMUX|=(1<<REFS0)+channel;
> Bevor Du die Mux-Bits veroderst, musst Du sie löschen, sonst sind> irgendwann die verwendeten Bits = 1 und ändern sich auch nicht mehr.
ADMUX = 0x00;? Bin mir aber über den Nutzen dessen nicht ganz bewusst.
Könntest du mich da nochmals aufklären? Ich will ja, dass das Register
so aussieht: 0b01000010;
Peter II schrieb:> Michael D. schrieb:>> uint16_t result=ADCL;// store low byte of sample value in variable>> result+=(ADCH<<8);// add high byte of sample value>> warum so kompliziert?>>
Nimm mal Vcc als Referenz, also:
ADMUX &= ~(1 << REFS0); // clear REFS0-Bit
und dann
ADMUX |= channel; // wenn channel <= 3
oder in einem step:
ADMUX = channel;
Michael D. schrieb:> ADMUX = 0x00;? Bin mir aber über den Nutzen dessen nicht ganz bewusst.
Könnte man, macht man aber nicht, man löscht nur die Mux-Bits, die neu
zu beschreiben sind und das muss auch nicht im Mux-Register selbst
passieren.
In Deinem Fall, da Du nur einen Kanal ansprichst, ändert das nichts, ist
also nicht der Fehler, wird aber zum Fehler, wenn die Funktion adc_read
mit mehr als einem Kanal aufgerufen wird.
In Deinem Fall hätte ein:
1
ADMUX=(1<<REFS0)+channel;
ausgereicht, um das zu korrigieren.
Aber auch das macht man üblicherweise nicht so, sondern man setzt die
Referenz einmal in einer Initialisierung und lässt die dann in Ruhe.
Verändert werden nur die Mux-Bits, die den Kanal bezeichnen, alle
anderen Bits lässt man in Ruhe.
MWS schrieb:> JoeS schrieb:>> oder in einem step:>>>> ADMUX = channel;>> Sicher nicht, da werden alle anderen Bits, REFS0 oder ADLAR gelöscht.
Ich meine das im Bezug auf die Initialisierung aus der ursprünglichen
Routine. Ist mir auch klar, daß man damit alle anderen Bits löscht,
aber so war es ja oben auch vorgesehen.
JoeS schrieb:> Ich meine das im Bezug auf die Initialisierung aus der ursprünglichen> Routine.
Egal wo Du's meinst, ist's falsch.
> ADMUX &= ~(1 << REFS0); // clear REFS0-Bit> und dann> ADMUX |= channel; // wenn channel <= 3> oder in einem step:> ADMUX = channel;
Denn in "in einem step" würde damit REFS0 gelöscht. Nur wenn man ADMUX =
channel ganz zu Anfang stellt und alle nachfolgenden Registerbits
verodert, würde das klappen, das wär' aber eine ungewöhnliche
Vorgehensweise.
MWS schrieb:> JoeS schrieb:>> Ich meine das im Bezug auf die Initialisierung aus der ursprünglichen>> Routine.>> Egal wo Du's meinst, ist's falsch.>>> ADMUX &= ~(1 << REFS0); // clear REFS0-Bit>> und dann>> ADMUX |= channel; // wenn channel <= 3>> oder in einem step:>> ADMUX = channel;>> Denn in "in einem step" würde damit REFS0 gelöscht. Nur wenn man ADMUX => channel ganz zu Anfang stellt und alle nachfolgenden Registerbits> verodert, würde das klappen, das wär' aber eine ungewöhnliche> Vorgehensweise.
Einzelne Anweisungen aus dem Kontext gerissen machen nie viel Sinn.
Deshalb nochmal im Ganzen:
Der TO wählte beim T13 die interne Referenz, hatte beim Arduino aber
Vcc als Referenz, wo es dann wohl funktionierte. Deshalb war mein
Vorschlag die Refernz beim T13 auch auf Vcc zu setzen: clear REFS0 bit
Um in der Routine nun den richtigen channel zu setzen müssen
die MUX0:1 0 sein um den Wert channel richtig zu odern.
Und wenn man nur die beiden MUX-Bits setzen will, dann geht
ADMUX = channel; sehr wohl in diesem Zusammenhang.
Peter D. schrieb:> Michael D. schrieb:>> Der ATTiny13 hat kein USART soweit ich weiß.>> Geht auch ohne HW-UART.> Schau einfach mal den Link an.
Ganz geschafft hab ichs nicht. Was genau muss an der Schaltung dafür
ändern?
Grüße
JoeS schrieb:> Der TO wählte beim T13 die interne Referenz, hatte beim Arduino aber> Vcc als Referenz, wo es dann wohl funktionierte. Deshalb war mein> Vorschlag die Refernz beim T13 auch auf Vcc zu setzen: clear REFS0 bit>> Um in der Routine nun den richtigen channel zu setzen müssen> die MUX0:1 0 sein um den Wert channel richtig zu odern.> Und wenn man nur die beiden MUX-Bits setzen will, dann geht> ADMUX = channel; sehr wohl in diesem Zusammenhang.
Hab ich schon versucht, leider tut sich dann garnichtsmehr. Als Referenz
Vcc wäre auch schon mein Plan gewesen, aber ohne Debugging/UART ist es
einfach so schwer was aus den dingern rauszubekommen. )=
JoeS schrieb:> Wieviel mV hast Du denn am Sensor?> Mal bitte mit dem Multimeter messen.
Bei Vcc=5V:
Trocken 3,2V
Nass 1,6V...
Es bahnt sich hier das Problem an... wie könnte ich das lösen? Er
vergleicht doch jetzt 5V zu 1,1V intern. oder wenn ich ADMUX =
~(1<<REFS0) setze 5V mit 5V, bekomm aber dafür mit poti und Sensor
nichts vernünftiges raus.
Michael D. schrieb:> Es bahnt sich hier das Problem an... wie könnte ich das lösen? Er> vergleicht doch jetzt 5V zu 1,1V intern. oder wenn ich ADMUX => ~(1<<REFS0) setze 5V mit 5V, bekomm aber dafür mit poti und Sensor> nichts vernünftiges raus.
ADMUX = ~(1 << REFS0);
ist falsch. Da setzt Du alle Bits auf 1 bis auf das REFS0 Bit.
JoeS schrieb:> Michael D. schrieb:>> Es bahnt sich hier das Problem an... wie könnte ich das lösen? Er>> vergleicht doch jetzt 5V zu 1,1V intern. oder wenn ich ADMUX =>> ~(1<<REFS0) setze 5V mit 5V, bekomm aber dafür mit poti und Sensor>> nichts vernünftiges raus.>> ADMUX = ~(1 << REFS0);>> ist falsch. Da setzt Du alle Bits auf 1 bis auf das REFS0 Bit.
Wahnsinn, bin ich ein Depp ._.
Hatte mir ja fast gedacht, dass es sowas ist, deswegen bin ich das
Programm eh mehrmals step-by-step durchgegangen, aber da wär ich noch
Wochen gesessen. Funkt einwandfrei jetzt. Großes Dankeschön :)
MWS schrieb:> JoeS schrieb:>> dann geht>> ADMUX = channel; sehr wohl in diesem Zusammenhang.>> Yep, das geht ist aber dennoch unsinnig.
Ist es nicht, unter Berücksichtigung des impliziten
Wunsches Adlar und REFS0 auf 0 zu setzen und die MUX-Bits
entsprechend auf 00 01 10 oder 11 zu setzen.
Vermutlich bestehst Du darauf es so zu formulieren, daß
wirklich nur die gewünschten MUXe gesetzt werden, was ja in einem
anderen Kontext auch Sinn macht, aber hier geht es, wie Du ja selber
sagst,
auch so.
JoeS schrieb:> MWS schrieb:>> Yep, das geht ist aber dennoch unsinnig.>> Ist es nicht, unter Berücksichtigung des impliziten
Wenn man die Schwierigkeiten des TE bei der Codeerstellung sieht, dann
ist so eine "Abkürzung" definitiv unsinnig.
Wikipedia:
Unsinn, auch Widersinn, ist ein von Sinn und Logik gelöster oder grob
falscher Sachverhalt – bisweilen (absichtlich) scherzhaft. Die
Eigenschaft eines solchen wird als Unsinnigkeit bezeichnet. Unsinnig
kann auch bedeuten: ohne erkennbaren Sinn.
MWS schrieb:> Wenn man die Schwierigkeiten des TE bei der Codeerstellung sieht, dann> ist so eine "Abkürzung" definitiv unsinnig.
Allerhöchstens undurchsichtig.
Joe S. schrieb:> Wikipedia:> Unsinn, auch Widersinn, ist ein von Sinn und Logik gelöster oder grob
Versuch' mal Brain V1.0 anstatt Wiki zu zitieren.
> Allerhöchstens undurchsichtig.
Unsinnig in Bezug auf den Nutzen für den TO, wobei "Unsinn" doch
freundlich ausgedrückt war. In Anbetracht seines auch für Dich
erkennbaren Kenntnisstandes wäre "böswillig" auch etwas, das mir da
einfällt. Nachher lernt der noch so 'nen Schmarrn.
MWS schrieb:> Unsinnig in Bezug auf den Nutzen für den TO, wobei "Unsinn" doch> freundlich ausgedrückt war. In Anbetracht seines auch für Dich> erkennbaren Kenntnisstandes wäre "böswillig" auch etwas, das mir da> einfällt. Nachher lernt der noch so 'nen Schmarrn.
Also,
n bischen mal selber nachvollziehen kann man vom TO schon erwarten.
Schlußendlich hat er es ja dann auch gemerkt.
MWS schrieb:> Unsinnig in Bezug auf den Nutzen für den TO, wobei "Unsinn" doch> freundlich ausgedrückt war. In Anbetracht seines auch für Dich> erkennbaren Kenntnisstandes wäre "böswillig" auch etwas, das mir da> einfällt. Nachher lernt der noch so 'nen Schmarrn.
Ah, darauf hab ich ja fast gewartet.
So als abschließendes Statement hätte ich noch gern eine perfekte
Schreibweise von MWS um das ganze Thema abschließen zu können und noch
was zu lernen:
Michael D. schrieb:> MWS schrieb:>> Unsinnig in Bezug auf den Nutzen für den TO, wobei "Unsinn" doch>> freundlich ausgedrückt war. In Anbetracht seines auch für Dich>> erkennbaren Kenntnisstandes wäre "böswillig" auch etwas, das mir da>> einfällt. Nachher lernt der noch so 'nen Schmarrn.>> Ah, darauf hab ich ja fast gewartet.> So als abschließendes Statement hätte ich noch gern eine perfekte> Schreibweise von MWS um das ganze Thema abschließen zu können und noch> was zu lernen:
Mach Dir nichts draus, manche Leute können einfach nicht anders.
Ich finde es gut, daß Du Dein Problem in den Griff gekriegt hast.