Archive for Februar 19th, 2012

Solar – Strommessung mit Hallsensor

Um die Leistung messen zu können, welche von meinem 100W-Solarpanel (Peak-Power) in einen 12V/20Ah-Akku eingespeist wird, habe ich eine kleine Elektronik gebastelt, welche mittels Hall-Sensor den Strom erfasst und über einen Operationsverstärker (TL072 – siehe Schaltplan) den Pegel für ein XBee-Modul anpasst,  welches dann die Daten zum Hausserver überträgt. Die Operationsverstärkerschaltung ist ein Differenzverstärker der das Signal des ACS714, welches bei 0 Ampere 2.5V liefert, auf eine Spannung zwischen 0V (für 0 Ampere) und 1.2V einstellt. Nach dem OPV Signal ist zum Entrauschen noch ein Tiefpassfilter eingebaut, welches die Signalqualität verbessert. Zum Erfassen der Messwerte werden die Analogen I/O Eingänge des XBee-Modules verwendet, welches alle 5 Minuten aufwacht und die Daten übermittelt. Übertragen werden die aktuelle Spannung des Akkus, sowie der Ladestrom. Am Hausserver werden die Daten in eine MySQL-Datenbank geschrieben und alle 15 Minuten mit einer Grafik visualisiert.

Die Spannungsversorgung erfolgt direkt vom Akku, wobei die ca. 12V mittels eines Pololu-Step-Down-Wandlers auf 5V für den Hallsensor vermindert werden, danach werden diese noch mittels eines LM1117-3.3 auf 3.3V für das XBee-Modul reduziert.

Als Hallsensor kommt ein ACS714 zum Einsatz. Da mir der 8 pin SOIC Chip für den Aufbau zu klein war habe ich mich für das Break-Out-Board von Pololu entschieden (http://www.pololu.com/catalog/product/1187)

Das Ergebnis sind die Grafiken im Anhang. Bei Interesse gerne mehr Informationen!

 

VN:F [1.9.22_1171]
Rating: 3.0/5 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 2 votes)

QR Code

Messung der Substratfeuchte von Pflanzen

Ich hatte im Wintergarten immer das Problem, dass je nach Sonneneinstrahlung, und der damit verbundenen Erwärmung, der Abstand zwischen dem Bewässern der Pflanzen sehr stark schwankte. Also sollten die Pflänzchen sich am Besten selbst melden, wenn sie durstig sind.

Umgesetzt wurde das Projekt mit einem MEGA-328P Microprozessor, welcher 8 Analoge Eingänge zur Verfügung stellt. Als Sensoren dienen Fühler der Firma Seeedstudio ( -> Link ). Die Datenübermittlung an den Hausserver erfolgt mittels eines XBee-Moduls. Am Hausserver läuft ein kleines Java Programm, welches die Daten des XBee Moduls empfängt und in eine MySQL-Datenbank überträgt. Aus dieser Datenbank werden die Werte ausgelesen, ausgewertet und Visualisiert. Auf meinem Hausserver läuft alle 10 Minuten ein Programm welches diese Auswertung erledigt und im Fall von Trockenheit eine SMS, sowie eine Email an mich versendet.

Ein Problem, welches mit den Fühlern auftrat ist, dass das Kupfer auf diesen nach ca. 3-4 Wochen auf der Plus-Pol-Seite wegoxidiert sind. Eine Möglichkeit wäre die Kontakte zu vergolden. Ich habe jetzt allerdings testweise in den Plus-Pol einen Niro-Schrauben eingebaut (Bild), der als Messsonde dienen soll. Es wird sich zeigen, ob dieser seine Funktion länger erfüllen kann.

Interessant war, zu beobachten, dass die Substratfeuchte bei Erwärmung (Sonneneinstrahlung) deutlich zu steigen begann und am Abend wieder abklingt. Dies ergibt über die Zeitspanne von mehreren Tagen eine wellenförmige Abwärtsbewegung in der Grafik. Umso stärker die Erwärmung, desto ausgeprägter dieser Effekt, den ich auf die Oberflächenverdunstung zurückführe.

Programmcode für Arduino:

Programmcode anzeigen

byte DEBUG = 0;
 
int i;
 
// Includes und defines für Sleep-Modus
#include <avr /sleep.h>
#include </avr><avr /wdt.h>
 
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
 
// Globale Variable Sleep Modus
volatile boolean f_wdt=1;
int sleepcount;
 
const byte XBee_Sleep_Pin = 2;  // Sleep Pin für Powersavemode XBee
 
void setup() {
 
  Serial.begin(9600); 
  Setup_Sleep();
 
  pinMode(13, OUTPUT);  
  pinMode(XBee_Sleep_Pin, OUTPUT);
 
  digitalWrite(XBee_Sleep_Pin, LOW);  // XBee aus Schlafmodus wecken  
 
  for (i=0;i&lt;10;i++) {          // Warteschleife, damit sich XBee verbinden kann
    digitalWrite(13, HIGH);   // set the LED on
    delay(50);              // wait for a second
    digitalWrite(13, LOW);    // set the LED off
    delay(50);              // wait for a second
  }
 
  //delay(15000);             // 5 Sekunden warten, bis XBee sicher da ist
}
 
 
 
 
void loop() {
 
  digitalWrite(XBee_Sleep_Pin, HIGH);  // XBee aus Schlafmodus wecken  -> Transistormodus, mit Widerständen LOW
 
  digitalWrite(13, HIGH);             // set the LED on  
  delay (18000);
 
  SendData("A0",A0);        // Fikus klein
  SendData("A1",A1);        // Bonsai
  SendData("A2",A2);        // Fikus groß
  SendData("A3",A3);        // Chilli
  SendData("A4",A4);        // Banane
 
 
  Serial.print("VCC=");
  Serial.print(readInternVcc());
  Serial.print(";EOL"); 
 
  delay (500);  
  digitalWrite(13, LOW);    // set the LED off  
  digitalWrite(XBee_Sleep_Pin, LOW);
 
  // Go to sleep
sleeploop_start:
  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag
    sleepcount++;
  }  
  if (DEBUG) { 
    Serial.print("Sleeping,"); 
    delay(10); 
  }
  system_sleep();
  if (DEBUG) Serial.println ("Wake Up");
  if (sleepcount < (300/8) ) goto sleeploop_start;  // Solange Zeit noch nicht abgelaufen nicht weiterspringen, sondern weiterschlafen -> Powersafe 300 = 5 Min
  sleepcount=0;  
  if (DEBUG) Serial.println("Nächste Messung...");  
 
}
 
void SendData(char *Bezeichnung, uint8_t Port) {
  long sensorValue = 0;
 
  int loops = 5;
  // read the value from the sensor:
  for (i=0;i<loops ;i++) {
    sensorValue += analogRead(Port);
    //delay(2);      // ADC beruhigen lassen-
  }
  sensorValue = round(sensorValue/loops);
 
 
  Serial.print(Bezeichnung);                       
  Serial.print("=");
  Serial.print(sensorValue);  
  Serial.print(";"); 
 
}
 
 
 
/************************************ Setup_SLEEP *********************************************************************/
void Setup_Sleep()
{
  // CPU Sleep Modes 
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)
 
  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode
 
  setup_watchdog(9);	// 9 = 8 sek. schlafen
} 
 
//****************************************************************  
// set system into the sleep state 
// system wakes up when wtchdog is timed out
void system_sleep() {
 
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
 
  sleep_mode();                        // System sleeps here
 
    sleep_disable();                     // System continues execution here when watchdog timed out 
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
 
}
 
//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
 
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1< &lt;5);
  bb|= (1<<WDCE);
  ww=bb;
  //Serial.println(ww);
 
 
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}
 
 
//****************************************************************  
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}
 
 
 
 
 
// Liefert Spannung in Millivolts retour, 5000 = 5V, 3300 = 3.3V
// http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
 
long readInternVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<&lt;8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}
VN:F [1.9.22_1171]
Rating: 4.0/5 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

QR Code

© Ing. Wolfgang Ruthner 2012-2013, Feldstraße 11A, 3300 Amstetten, Austria
iDream theme by Templates Next | Powered by WordPress