Login
Register
Forum
Kontakt
Bitmania
2015-05-14 11:25
by bitman
Wasserstandmessung Revision
RFM12 Network

der Wasserstands-Sensor hat ein paar Nachteile die eine Überarbeitung notwendig machen.
Eines vorweg: Dies ist erstmal ein Zwischenstand bei dem ich neue Erkenntnisse gewonnen habe. Ich arbeite noch an einer weiteren Version, im Moment fehlt mir noch die zündende Idee.

Dies ist ein Bild der Version 1 (die Stangen sind tatsächlich 1m lang, nur im Bild habe ich sie gekürz):





Funktionsprizip 1. Version:
Zwei Metallstangen (1m lang, 4mm Durchmesser) stecken parallel in einem U-Förmig angeordneten PVC-Schlauch. Diese bilden einen Kondensator welcher senkrecht im Wasser steht. Je nach Wasserstand ergibt das eine unterschiedliche Kapazität dieses Kondensators,
Der ATMega lädt diesen Kondensator und misst die Zeit, die es dauert ihn über einen definierten Widerstand wieder zu entladen. Die Zeit ist proportional zum Wasserstand.

Nachteil:
In einem neuen Aufbau will ich den RFM12 Sensor nicht direkt an der Wassertonne anbringen sondern über ein längeres Kabel mit dem Wasserstands-Sensor verbinden. Tests mit einem 6m Kabel haben ergeben das sich dabei Störeinflüsse bemerkbar machen.
Wenn ich z.B. das Kabel etwas anders verlege komme ich zu anderen Messergebnissen.
Ein weiterer Störfaktor sind vermutlich elektrische Felder die das Ergebniss ebenfalls verändern wenn sich der Sensor oder das Kabel in der Nähe einer Stromleitung, einer Steckdose oder eines Verbrauchers befindet.

Man sieht das hier sehr schön mit dem Sensor (die Stangen) welche sich nicht im Wasser sondern auf meinem Schreibtisch befinden. Die Messergebnisse müssten also gleich sein. Also immer ohne Wasser, quasi Pegelstand Null. Die Sprünge in dem Messergebnis sind immer dann zustande gekommen wenn ich den Sensor oder das Kabel umgelegt habe, oder elektrische Verbraucher in der Nähe ein/aus geschaltet habe.






Version 2

Ich hab mir daher für die Version 2 etwas anderes überlegt und zwar einen Oszillator, welcher sich direkt an dem Stangen-Kondensator befindet. Er wird mit einer Versorgungsspannung und GND versorgt und liefert das Messergebnis als ein Rechtecksignal an den entfernten RFM12 Funksensor. Die Frequenz entsprcht dem Wasserstand.

Der Oszillator besteht aus einem HCF4011, einem Widerstand und dem Stangenkondensator der im Wasser steht.






Ich habe einen HCF4011 gewählt, weil er schon ab 3V Versorgungsspannung arbeitet.

Den Code für den RFM Sensor musste ich überarbeiten weil ich nun nicht mehr das Übersteigen der Kondensator Bandgap-Spannungreferenz zur Zeitmessung verwende sondern über PB0 ICP1 Timer1 Input Capture auslöse. Im Grunde eine Frequentzmessung des Rechtecksignals. Ich spare dazu gegenüber der Version 1 sogar noch den Pin PD6 ein, da ich ihn nicht mehr für die Nutzung des Band-Gap Setup blockiere. Den Oszillator schalte ich über PIN PD4 nur dann an wenn gemessen werden soll.

Das Ergebnis ist vielversprechend. Reine Positionsänderungen scheinen sich kaum noch auszuwirken. Das einzige was mich jetzt noch stört ist eine Abweichung des Messergebnisses bei Temperaturänderungen. Ich habe hier mal einen Test gemacht und einen Kühlakku auf den Sensor gelegt (und wieder abgenommen).




Jetzt müsste ich als nächstes mal ausprobieren wie stark sich Temperaturänderungen auf den gemessenen Pegelstand auswirken. Also ob man das vernachlässigen kann (wenige mm) oder ob das noch nicht der letzte Schluss ist (> mehrere cm)


Vorbereiten Timer1 usw:

TIMSK1 = (1 << TOIE1); // enable Timer1 overflow interrupt
// CS12 CS11 CS10 Description
// 0 0 0 No clock source (Timer/Counter stopped).
// 0 0 1 clk I/O /1 (No prescaling)
// 0 1 0 clk I/O /8 (From prescaler)
// 0 1 1 clk I/O /64 (From prescaler)
// 1 0 0 clk I/O /256 (From prescaler)
// 1 0 1 clk I/O /1024 (From prescaler)
// 1 1 0 External clock source on T1 pin. Clock on falling edge.
// 1 1 1 External clock source on T1 pin. Clock on rising edge.
TCCR1B |= (1 << CS10); // Set CS10 bit so Timer1 runs at clock speed

sei(); // Enable Interrupts

GetWaterLevel(10);


Die Messfunktion:

uint16_t GetWaterLevel( uint8_t nsamples ) {
uint16_t x;
uint16_t min ;
min = 0xffff;
PORTD |= (1<<4); // turn on oscillator
_delay_ms(100); // give the oscillator some time to settle

for (uint16_t i = 0; i < nsamples; ++i ) {
edge_count = 0;
edge_t1 = 0;
edge_t2 = 0;
while(TCNT1>10){} // wait until TCNT1 has low value
TIMSK1 = (1<<ICIE1); // enable ICP-Interrupt

while(edge_t2==0 && TCNT1!=0){} // wait until edge_t2 is ready (measurement finished), timeout if TCNT1 overflow
x = edge_t2-edge_t1;
if(x<min && x>=500) min=x;

TIMSK1 &= ~(1<<ICIE1); // disable ICP-Interrupt
//_delay_ms(12);
//usart_write("%i
",min);
}
PORTD &= ~(1<<4); // turn off oscillator
return (uint16_t)( min );
}


Die Interruptroutine:

ISR(TIMER1_CAPT_vect) { // for the water level sensor (this interrupt fires when PB0 gets high)
//PORTC ^= (1 << 2); // PC2 toggle (test only, to trigger the scope)
if(edge_count==0) edge_t1 = ICR1; // start value
if(edge_count==1) edge_t2 = ICR1; // stop value
edge_count++;
}





1 Comment

bitman 2017-07-09 11:57 ^ 403

Moderator
Posts: 109
Pages: 99
Registered: 2010-07-09
Vor 2 Jahren habe ich diese Wasserstandssensoren gebaut. Inzwischen kann ich sagen das sie nur in den ersten Monaten gut funktioniert hatten.
Die Stangen steckten ja in PVC Schläuchen was sie waserdicht verschließen sollte. Leider scheint wohl doch in beide Wasser eingedrungen zu sein, denn die Stangen waren rostig und der Sensor lieferte keine Werte mehr.
Ich habe nun eine Idee für eine andere Messmethode, und habe auch schon angefangen daran zu arbeiten. Dazu folgt in Kürze ein Bericht.