Bienenstockwaage jetzt stabil wireless

Das ist Eintrag 12 in der Serie "Bienenwaage".

Der Bauanleitungen dieser Serie sind veraltet. Aktuell ist die Serie Bienenkiste 2.0.

P1050109
Die aktuelle Schaltung mit Wägezelle, Temperatursensor und Reset

Wers noch nicht gemerkt hat: Der Bienenwaagenprobelauf ist seit einiger Zeit umgestellt auf Wireless. Das Redfly-Shield von Watterott bildet die Hardware und ersetzt das Ethernet-Shield. Die Schaltung (siehe Abbildung) ist die gleiche wie beim Ethernetbetrieb – fast: Sie ist ergänzt um eine OneWire-Reset-Schaltung (mit Diode) , zu sehen als roter Verbinder quer über das Redfly-Shield. Die Auto-Resetschaltung ist nötig, da – warum auch immer, für Erklärungsversuche bin ich dankbar – sich die Wireless-Verbindung regelmäßig aufhängt und die Sensorik dann nicht mehr erreichbar war. Beim Sketch handelt es sich um den abgewandelten Ethernet-Sketch, erweitert um die Resetschleife und mit anderem Pin für den Temperatursensor unten rechts im Bild (weil ich den Sensor nicht auf einem Pin lassen wollte, er vom Redfly belegt ist). 

Ethernet funktioniert zwar, aber wer will schon immer ein Kabel quer durch den Garten? Erste Versuche mit einem xbee-Modul haben aber gezeigt, dass funken gar nicht so einfach ist. Erstens ist dieser wlan-Adapter kompliziert zu konfigurieren (zumindest will mir das so scheinen). Und zweitens sind W-Lan-Verbindungen von Natur aus instabiler als Kabel, d.h. die Programme, die solche Verbindungen nutzen, müssen viel robuster und fehlerresistenter programmiert sein – daher der Notnagel Reset-Schaltung.

Ich bin kein Coder. Also bin ich mit dem Sketch zufrieden, weil er stabil funktioniert. Wer Umständlichkeiten findet oder Fehler oder Vorschläge hat, wie das Ganze oder Teile davon einfacher oder schöner zu lösen sind: Her damit!

Sketch zum Download

/*
Open Bee Hive Scale Wireless
2014-07 by mois
Dieser Sketch von mois ist lizensiert unter einer Creative Commons
Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen
Bedingungen 4.0 International Lizenz.
This code by mois is licensed under a Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International License.
*/

//wlan hangs every once in a while
//so we auto-reset every once in a while
int resetPin = 12;
long int interval = 300000;  // reset alle 5 minuten
long int time = 0;

// load cell characteristic
// define here individual values for used load cell type
//
// - 11994383 sensor value for "0 kg"
//   write down the sensor value of the scale with no load and adjust it
here
// - 6016676 is the value for a 1 kg weight load
//   add a load with known weight in kg to the ceall, note the sesor
value, calculate
//   the value for a 1 kg load and adjust it here
long loadCellZeroOffset = 6800000;
long loadCellKgDivider = 6016676;

#include <RedFly.h>
#include <RedFlyServer.h>
byte ip[]      = { 192,168,178, 29 }; //ip from shield (server)
byte netmask[] = { 255,255,255,  0 }; //netmask
//initialize the server library with the port
//you want to use (port 80 is default for HTTP)
RedFlyServer server(80);

#include <ADS1231.h>
ADS1231 loadCell;  // create ADS1231 object
long weightSensorValue;
float weightKg;
boolean weightKgTrusted = false;

#include <RunningMedian.h>
// RunningMedian sample size is 11
RunningMedian weightSamples = RunningMedian(11);  // create
RunningMedian object

#include <SPI.h>

#include <OneWire.h>
int pin_number = 4; //DS18S20 Signal pin on digital 4
OneWire ds(pin_number);
float temp;

// debug
long outputLines = 0;

//debug output functions (9600 Baud, 8N2)
//Leonardo boards use USB for communication, so we dont need to disable
the RedFly
void debugout(char *s)
{
#if defined(__AVR_ATmega32U4__)
Serial.print(s);
#else
RedFly.disable();
Serial.print(s);
RedFly.enable();
#endif
}

void debugoutln(char *s)
{
#if defined(__AVR_ATmega32U4__)
Serial.println(s);
#else
RedFly.disable();
Serial.println(s);
RedFly.enable();
#endif
}
void setup()
{
digitalWrite(resetPin, HIGH);
delay(200);
// initialize the digital pin as an output.
pinMode(resetPin, OUTPUT);
//RedFly.disable();
//Serial.begin(9600);//initialize Serial Port
//Serial.println("reset");  //print reset to know the program has been
reset and the setup function happened
//RedFly.enable();
delay(200);

uint8_t ret;

#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
Serial.begin(9600); //init serial port and set baudrate
while(!Serial); //wait for serial port to connect (needed for Leonardo
only)
#endif

//init the WiFi module on the shield
// ret = RedFly.init(br, pwr)
//br=9600|19200|38400|57600|115200|200000|230400,
pwr=LOW_POWER|MED_POWER|HIGH_POWER
ret = RedFly.init(115200, HIGH_POWER);
if(ret)
{
debugoutln("INIT ERR"); //there are problems with the communication
between the Arduino and the RedFly
}
else
{
//scan for wireless networks (must be run before join command)
RedFly.scan();
//join network
// ret = join("wlan-ssid", "wlan-passw") //join infrastructure
network with password
ret = RedFly.join("wlan-a71-intern", "5606310369512311");
// delay(2000);
if(ret)
{
debugoutln("JOIN ERR");
for(;;); //do nothing forevermore
}
else
{
//set ip config
// ret = RedFly.begin(); //DHCP
// ret = RedFly.begin(ip, dnsserver, gateway, netmask);
ret = RedFly.begin();
// delay(2000);
if(ret)
{
debugoutln("BEGIN ERR");
RedFly.disconnect();
for(;;); //do nothing forevermore
}
else
{
RedFly.getlocalip(ip); //receive shield IP in case of DHCP/Auto-IP
server.begin();
}
}
}
// load cell / ADS1231 pin definition: SCL 8, Data 5, PowerDown 9
loadCell.attach(8,5,9);
}

void loop()
{
//listen for incoming clients
if(server.available())
{
//a http request ends with a blank line
boolean currentLineIsBlank = true;
while(server.available())
{
char c = server.read();
//if you've gotten to the end of the line (received a newline
//character) and the line is blank, the http request has ended,
//so you can send a reply
if(c == '\n' && currentLineIsBlank)
{
//clear input buffer
server.flush();
// get sensor data
RedFly.disable();
temp = getTemperature();
// ADS1231 ready?
if (loadCell.check())
{
// delay(1000);
// read input of ADS1231:
weightSensorValue = loadCell.readData();
// calculate weight in kg
weightKg = ((float)weightSensorValue - loadCellZeroOffset) /
loadCellKgDivider;
// add data to runnig median sample
weightSamples.add(weightKg);
// complete sample?
if (weightSamples.getCount() == weightSamples.getSize())
{
weightKgTrusted = true;
}
}
RedFly.enable();

//send standard HTTP 200 header
server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type:
text/html\r\n\r\n"));
server.println_P(PSTR("<!DOCTYPE HTML>"));
server.println_P(PSTR("<html>"));
server.print_P(PSTR("<meta http-equiv=\"refresh\"
content=\"0;URL=http://www.euse.de/honig/beescale/add_line2.php?kiste1="));
server.print(weightKg, 3);
server.print_P(PSTR("&temp="));
server.print(temp, 1);
server.println_P(PSTR("\"); ?>"));
server.println_P(PSTR("</html>"));
break;
}
if(c == '\n')
{
//you're starting a new line
currentLineIsBlank = true;
}
else if(c != '\r')
{
//you've gotten a character on the current line
currentLineIsBlank = false;
}
}
// give the web browser time to receive the data
delay(1000);
//close connection
server.stop();
}
else if(!server.connected()) //listening port still open?
{
server.stop(); //stop and reset server
//delay(1000);
server.begin(); //start server
//delay(1000);
}

//  delay(1000);               // wait for a second
//  RedFly.disable();
//  Serial.println("resetting");
//  delay(10);
time = millis();
//  Serial.println(time);
if(time > interval)
{
digitalWrite(resetPin, LOW);  //Pulling the RESET pin LOW triggers the
reset.
}
//  Serial.println("this never happens");
//  RedFly.enable();        //this never happens because Arduino resets
}

#define DS18S20_ID 0x10
#define DS18B20_ID 0x28
boolean getTemperature(){
byte i;
byte present = 0;
byte data[12];
byte addr[8];
//find a device
if (!ds.search(addr)) {
ds.reset_search();
return false;
}
if (OneWire::crc8( addr, 7) != addr[7]) {
return false;
}
if (addr[0] != DS18S20_ID && addr[0] != DS18B20_ID) {
return false;
}
ds.reset();
ds.select(addr);
// Start conversion
ds.write(0x44, 1);
// Wait some time...
delay(850);
present = ds.reset();
ds.select(addr);
// Issue Read scratchpad command
ds.write(0xBE);
// Receive 9 bytes
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
// Calculate temperature value
temp = ( (data[1] << 8) + data[0] )*0.0625;
return temp;
}

Wie weiter? Siehe aktualisierte Todo-Seite!

Series Navigation<< Bienenwaage: Prototyp im Testlauf (Bauanleitung)Bienenwaage: Todo >>

7 Gedanken zu „Bienenstockwaage jetzt stabil wireless“

  1. Gibt es Erklärungen für die Ausschläge im Testbetrieb? Das sind ja doch +/- 2,5 kg ab und an. Mein Testaufbau war im Wohnzimmer auf einem Diehlenboden und da haben die Schwingungen wohl die Messergebnisse etwas beeinflußt. Aber 2 kg waren das nicht. Eher im 50 g Bereich. Mein Testsetting stand aber auch nicht so lange.

  2. ja, die erklärung: die waage steht unter dem tisch, an dem ich an der schaltung arbeite. daher gibt es immer, wenn ich was ausprobiere, zum bsp. intuppern der schaltung die ausschläge, weil ich mich auf den tisch lehne, die zange ablege, den rechner abstelle usw.

  3. Sehr interessiert lese ich die Ausführungen zu der Waage. Wäre es wohl möglich direkt einen rasp pi anstatt dem Arduino zu verwenden? So einen habe ich nämlich schon und ein Gertboard dazu.

  4. ja, wäre halt ein ganz anderes hardwaredesign, das auch auswirkung auf die programmierung hat. raspi macht bei uns allenfalls den server zur auswertung/darstellung der daten. gertboard hab ich gar keine erfahrung. aber berichte doch gerne, wenn du es ausprobierst.

  5. Hallo

    ich würde mir gern so eine Bienenstockwaage nachbauen.
    Gibt es für die Stockwaage eine Bauanleitung + Schaltpläne?

    Vielen Dank im voraus J. Weigel

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert