Tuesday 16 December 2014

ArduinoHomeAutomationProject: The Bridge-Processing-Software

The BridgeProcessing-Software


Overview in Processing


THE CODE

This is my approach to store serial-data into a SQL Database. I will describe the RPI Setup later.
import processing.serial.*;
import de.bezier.data.sql.*;
import java.util.*; 
MySQL db;
Serial myPort;  // Create object from Serial class
int myaddr = 1;
int addr;
int numeric;
int ldr;
int heat;
int light;
int node = 1;
int nodec = 1;
long setTimer = 120000;
int commandtimer = 10000;
int nrofnodes = 2;
int timerflag = 0;
int commandflag = 0;
int x = 1;
int i = 0;
int addrset;
int tempmin;
int hummin;
int lightsw;
int heatsw;
int setflag;
String TIME;
String TIMESTAMP;
String room;
float temp;  
float hum;
long oldmillis;
long newmillis;
long oldcommandmillis;
long oldutchour;
long newutchour;
int utcflag = 0;
long utc;
char c;
String inData;
String[] list = new String[32];
String inDatapl;
String[] listpl = new String [32]; 
char utch = '@';
char sof = '#';
char dof = '/';
char plm = 'P';
char eof = '|';
char rf = '0';
char wf = '1';
char ack = '2';
char set = '3';
int flag;
void setup()
{
   size(640, 360);
   smooth();
   String portName = Serial.list()[2];
   myPort = new Serial(this, portName, 19200);
   myPort.buffer(64);
   myPort.bufferUntil(eof);
 
   String user     = "youruser";
   String pass     = "yourpass";
   String database = "ahap"; //DBName
   db = new MySQL( this, "localhost", database, user, pass );
}
void draw()
{
  newmillis = millis();
  newutchour = hour();
  //serial.Event(myPort);

  readSerial();
  if (newmillis - oldmillis > setTimer/(nrofnodes-1) || timerflag == 0 || commandflag == 1) // || commandflag == 1
  {
    commandflag = 0;
    timerflag = 1;
    writeSerial();
    oldmillis = millis();
  }
  if (millis() - oldcommandmillis > commandtimer/(nrofnodes-1))
  {
   oldcommandmillis = millis();
   writeSerialCommand();
  }
   if (newutchour != oldutchour || utcflag == 0)
  {  
    oldutchour = hour();
    utcflag = 1;
    calculateutc();
  }
  background(0);
  textSize(20);
  //int y=x+1;
  text("Addresse: " + node , 50, 30);
  text("Raum: " + room , 350, 30);
  textSize(16);
  text("Daten von: data-DB", 50, 50);
  text("Daten von: data_set-DB", 350 , 50);
  textSize(14);
  text("Temperatur: " + temp/10, 50, 80);
  text("Feuchtigkeit: " + hum/10, 50, 100);
  text("Heizung: " + heat, 50, 120);
  text("LDR: " + 0.1*ldr, 50, 140);
  text("Licht: " + light, 50, 160);
  text("letzter Kontakt: " + TIME, 50, 180);

  text("Msg OUT: " + sof + addrset + dof + myaddr + dof + wf + dof + tempmin + dof + hummin + dof + lightsw + dof + heatsw + eof, 50, 240);
  text("TIMEstamp: " + utch + hour() + dof + minute() + dof + second() + dof + day() + dof + month() + dof + year() + eof, 50, 280);
  text("Durchlauf " + i , 50, 220);
  text("Msg IN: #" + list[0] + dof + list[1] + dof + list[2] + dof + list[3] + dof + list[4] + dof + eof, 50, 260);
  text("Anzahl Nodes " + nrofnodes , 50, 300);
  text("Node " + node , 50, 320);

  text("soll Temperatur: " + tempmin, 350, 80);
  text("soll Feuchtigkeit: " + hummin, 350, 100);
  text("Heizung ein/aus: " + heatsw, 350, 120);
  text("Licht ein/aus: " + lightsw, 350, 140);
  text("eingestellt am: " + TIMESTAMP, 350, 180);
  //calculateutc();
  }

 void readSerial()
 {
   if (myPort.available() >0)
   {  delay(50);
      c = myPort.readChar();
      if ( c == sof )
      {
        inData = myPort.readStringUntil(eof);
        if(inData != null){
        list = split(inData, "/");
        print("Empfänger: ");
        println(list[0]);
        print("Sender: ");
        addr = int(list[1]);
        println(list[1]);
        print("Flag: ");
        println(list[2]);
        flag = int(list[2]);
        int listcount = list.length;
        print("Listenfelder: ");
        println(listcount);
     
        if (listcount > 8){
          //println("FLAG ACK ERKANNT");
          print("Temperatur: ");
          temp = int(list[3]);
          println(temp/10);
          print("Feuchtigkeit: ");
          hum = int(list[4]);
          println(hum/10);
          print("Heizung: ");
          heat = int(list[5]);
          println(heat);
          print("LDR: ");
          ldr = int(list[6]);
          println(0.1*ldr);
          print("Licht: ");
          light = int(list[7]);
          println(light);
          println(" ");
          sqlset();
          inData = null;
          }
                     
         if (listcount < 8){
             //println("FLAG SET ERKANNT");
             //inData = myPort.readStringUntil(eof);
             //if(inData != null){
             //list = split(inData, "/");
             print("Heizung: ");
             heat = int(list[3]);
             println(heat);
             print("Licht: ");
             light = int(list[4]);
             println(light);
             commandflag = 1;
             sqlupdate();
             inData = null;
           
             }
               
         }
        }
      }
   
 
    else {
      myPort.clear();
    }
    //delay(1);
    //myPort.clear();
 }

 void writeSerial()
 { println("write Serial");
   i= i+1;
    if (node <= nrofnodes)
   {
     node++;
   }
  if (node == nrofnodes + 1 || node == 0)
  {
     node = 2;
   }
   db.connect();
 if(db.connect() == true)
  {    
   db.query( "SELECT COUNT(*) FROM room_set" );
   db.next();
 
   nrofnodes = db.getInt(1);


   db.query( "SELECT  `TIME` FROM `data` WHERE addr=('%s') ORDER BY ID DESC LIMIT 1", node);
   db.next();
   TIME = db.getString("TIME");
 
   db.query( "SELECT  `room` FROM `room_set` WHERE addr=('%s')", node);
   db.next();
   room = db.getString("room");
 
   db.query( "SELECT  `addr`, `tempmin`, `hummin`, `lightsw`, `heatsw`, `TIME` FROM `data_set` WHERE addr=('%s') ORDER BY TIME DESC LIMIT 1", node);
   db.next();
   addrset = db.getInt("addr");
   tempmin = db.getInt("tempmin");
   hummin = db.getInt("hummin");
   lightsw = db.getInt("lightsw");
   heatsw = db.getInt("heatsw");
   TIMESTAMP = db.getString("TIME");

   myPort.write(char(sof));
   myPort.write(str(addrset));
   myPort.write(char(dof));
   myPort.write(str(myaddr));
   myPort.write(char(dof));
   myPort.write(str(rf));
   myPort.write(char(dof));
   myPort.write(str(tempmin));
   myPort.write(char(dof));
   myPort.write(str(hummin));
   myPort.write(char(dof));
   myPort.write(str(lightsw));
   myPort.write(char(dof));
   myPort.write(str(heatsw));
   myPort.write(char(eof));

  }
 db.close();
 
 }

 void writeSerialCommand()
 {
    println("write Serial Command");
  if (nodec <= nrofnodes)
   {
     nodec++;
   }
  if (nodec == nrofnodes + 1 || nodec == 0)
  {
     nodec = 2;
   }
  db.connect();
  if(db.connect() == true)
    {    
     db.query( "SELECT COUNT(*) FROM room_set" );
     db.next();
     nrofnodes = db.getInt(1);
   
     db.query( "SELECT  `addr`, `tempmin`, `hummin`, `lightsw`, `heatsw`, 'setflag', `TIME` FROM `data_set` WHERE addr=('%s') ORDER BY TIME DESC LIMIT 1", nodec);
     db.next();
     
       addrset = db.getInt("addr");
       tempmin = db.getInt("tempmin");
       hummin = db.getInt("hummin");
       lightsw = db.getInt("lightsw");
       heatsw = db.getInt("heatsw");
       //setflag = db.getInt("setflag");
       TIMESTAMP = db.getString("TIME");
     
     // if (setflag == 1){
       myPort.write(char(sof));
       myPort.write(str(addrset));
       myPort.write(char(dof));
       myPort.write(str(myaddr));
       myPort.write(char(dof));
       myPort.write(str(wf));
       myPort.write(char(dof));
       myPort.write(str(tempmin));
       myPort.write(char(dof));
       myPort.write(str(hummin));
       myPort.write(char(dof));
       myPort.write(str(lightsw));
       myPort.write(char(dof));
       myPort.write(str(heatsw));
       myPort.write(char(eof));
      // setflag = 0;
      //}
   
     db.close();
     if (x == nrofnodes)
       {
       x=1;
       }  
   }
 }  
 void sqlset()

 {
   db.connect();
   if(db.connect() == true)
  {
    db.query("INSERT INTO data (addr, temp, hum, ldr, heater, light) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')",addr, temp/10, hum/10, ldr*0.1, heat, light);
    db.close();
  }
 }

void sqlupdate()

 {
   db.connect();
   if(db.connect() == true)
  {
    db.query("UPDATE data_set SET heatsw =%s, lightsw =%s, setflag = %s WHERE addr='%s' ", heat, light, setflag, addr);
    db.close();
  }
 }

 void calculateutc()
 {
   println("calculateUTC");
   delay(500);
   myPort.write(char(utch));
   myPort.write(str(hour()));
   myPort.write(char(dof));
   myPort.write(str(minute()));
   myPort.write(char(dof));
   myPort.write(str(second()));
   myPort.write(char(dof));
   myPort.write(str(day()));
   myPort.write(char(dof));
   myPort.write(str(month()));
   myPort.write(char(dof));
   myPort.write(str(year()));
   myPort.write(char(eof));
   delay(10);
   println("TimeSET");
   //myPort.clear();
 }

ArduinoHomeAutomationProject: The BridgeNode: PROTOTYPE & SKETCH (USE AT OWN RISK!!!)

The BridgeNode: PROTOTYPE & SKETCH (USE AT OWN RISK!!!)

The bridge is handling the data from the RaspberryPI SerialPort. I decided to take the USB Serial because there is no need to add a voltage divider (RPI 3,3V Logic, Arduino 5V Logic). The Incoming data is forwarded over the SoftwareSerial (RS485) while setting the DE Pin of the MAX485 high.
This is working for both directions. It is working at the moment, but i have to test it with more nodes to check for timing mismatches.

The Setup is an ArduinoNano + MAX485. 




THE CODE

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
void setup()
{
  Serial.begin(19200);
  mySerial.begin(19200);
}
void loop()
{  mySerial.listen();
  if (mySerial.available())
    Serial.write(mySerial.read());
    //delay(1);
  if (Serial.available())
    mySerial.write(Serial.read());
    delay(2);
}

TheSUN; Arduino powered wall clock; synced by AHAP


THESun; Arduino powered wall clock

Hi folks! A few days ago i decided to release my second Instructable about building an Arduino powered wall clock made of acrylic glass. Personally I am very satisfied with the result.
I attached some fotos here. The description itself can be found on Instructables.com just follow this LINK.

Startsequence

TheSUN in action



Fritzing







Impressum

Auer Markus
Karwendelstr. 13
A - 6020 Innsbruck