Send and receive

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

The last days I’ve been playing around with my JeeLink and a JeeNode including three sensors. I made a JeePlug with the TMP36, an LDR and a TSOP infrared receiver, which I can plug into my JeeNode. So I don’t have to plug everything in a breadboard and connect the wires, just place the JeePlug on top of my JeeNode in ports 1 and 4. I use port 1 for the temperature (TMP36) on the analog pin and I use the analog pin of port 4 for the LDR. The TSOP is connected to the digital pin of port 4 which leave the digital pin of port 1 empty to be used in the future.

The goal is to create a WSN based on several JeeNode and a Jeelink as central node. The JeeLink/JeeNode have a RF12Demo sketch with which it is possible to easily create a mesh network. The JeeLink is connected to a computer through USB. JeeNodes can communicate wirelessm using the on board RF12 chipset. All you have to do is configure the two units s that they can ‘find’ each other. See POF03 @ JeeLabs for an instruction on how to do that.

After I made the setup of my nodes and got the sketch started I saw data being displayed in my serial monitor. The JeeNode (sensor node) displayed information about the light and temperature on screen and sent the data to the JeeLink. I saw valid messages in the serial monitor of the JeeLink. The data shown by the JeeLink was something like:

OK 33 103 113 175 65

This line contains the measured temperature sent by the JeeNode. I knew that the value measured and sent was related to 21.93 degrees Centigrade. So somewhere in the sequence could be found. When you take a look at the Arduino Reference page about float (floating-point variables) you find that a float is represented by 4 bytes. So 4 of the 5 numbers in the message will together form the floating point number.

I wanted to know what 4 bytes were sent by the JeeNode so I did put in some extra Serial.print statements to display not only the measured temperature of (in this case) 21.93 degrees but I also the seperate bytes. To do this I had to ‘convert’ the float into an array of bytes. The lines below show you how:

float temperature;
byte  *ArrayOfFourBytes;

temperature = 21.93;

ArrayOfFourBytes = (byte*)&temperature;

Serial.println(temperature); // print the temperature

Serial.println(ArrayOfFourBytes[0],BIN); // print the 'first' byte in binary notation
Serial.println(ArrayOfFourBytes[1],BIN); // print the 'first' byte in binary notation
Serial.println(ArrayOfFourBytes[2],BIN); // print the 'first' byte in binary notation
Serial.println(ArrayOfFourBytes[3],BIN); // print the 'first' byte in binary notation

The printed binary numbers were:

1100111
1110001
10101111
1000001

In decimal notation equal to 103, 113, 165 and 65 which are the last 4 numbers of the received message. This still doesn’t look like 21.93 but we’re getting there.

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

A float is represented by 4 bytes which are equal to 32 bits. The printed binaries above are not all 8-bits but three of them are 7-bits. This is because the preceding zero’s are left out and you have to place them yourself in front of the 7-bits.
Al together these 32-bits give you three pieces of the puzzle; a sign, a exponent and a mantisse.

The formula for a IEEE 754 float is:  sign * 2exponent * mantissa  , where sign is +1 or -1

There are many of pages that explain more about floating-point numbers and their representation in bits, together with formulas. You can also find websites with converters that let you enter a number in the different representations and show that number in a binary, hexadecimal, float or decimal representation. I used this website.

I entered 21.93 in the converter and got 01000001 10101111 01110000 10100100 (in bytes this is equal to 65 175 112 164). This isn’t equal to 103, 113, 165 and 65; except for the 65 which might be a coincidence or not.
When I entered the original bit sequence with preceding zeros 01100111 01110001 10101111 01000001 I got the float number 1.1413232E24 and not 21.93.

I know that there are more possibilities of ordering and combining bytes to get e.g. a float. You have big-endian and little-endian (see Wikipedia about Endianness). This has a relation with the hardware platform you are using.

So I tried the sequence: 01000001 10101111 01110001 01100111 (which takes the ‘last’ byte first, then the third, second and first byte). The converter now gave me the floating-point number  21.930372 which is not exactly 21.93 but close enough to continue.

The explanation for the difference between 21.93 and 21.930372 can be found on the Arduino Reference page about Serial.print. Where the second example shows: Serial.print(1.23456) gives “1.23”, in other words the float is rounded or capped to two decimals.

This difference also explains the difference in bit sequence returned by the converter.

Knowing this I can continue sending, receiving and translating data to build my own WSN solution with central reporting functionality.

 

LDR and the JeeNode

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

In a previous post I gave an example of an LDR with the Arduino. In case you want to use it with a JeeNode you can connect the LDR between the AIO and GND. JeeLabs has a great page about LDR in combination with the on-board RF12 chipset to transmit the data between two nodes. A first step to your own Wireless Sensor Network (WSN).

I’ll give a small code sample just to read the measure light values when the LDR is connect between AIO (A) and GND (G) of port 3 of your JeeNode. For the extended code version please visit the original page at JeeLabs.

#include <Ports.h>
#include <RF12.h>

Port ldr (3);

void setup () {
    Serial.begin(57600);
    ldr.mode2(INPUT);
    ldr.digiWrite2(1);
}

void loop()
{
    // Measure value; convert the 0..1023 value to a 0.255 value
     byte value = 255 - ldr.anaRead() / 4;

    // Print the 'light  value'
    Serial.println((int) value);

   // wait for a second
    delay(1000);
}

 

 

 

 

Synology and Java

For now it like to investigate the use of a Synology (DS-107+) NAS together with Java. This might be a good way to connect a JeeNode/Arduino to the internet. In the future I like to use a Raspberry Pi to connect to the internet, together with other functions of course.
Important is that I can run Java code in combination with the serial communication capabilities of the rxtxSerial library. I found a really nice post on how to install Java on a Synology, because I really don’t want to loose the steps described I’ll cite the text of the post below:


1. install ipkg
http://forum.synology.com/wiki/index.php/How_to_Install_Bootstrap

2. install jamvm

To start with you need to install the following packages with ipkg:

ipkg install classpath
ipkg install jamvm
ipkg install jikes
ipkg install zlib
ipkg install file

Once these have installed then you are almost ready to go.  Being a java developer, I was used to using javac and java to compile and execute programs, so jikes and jamvm didn’t sit well with me!  To get around this I created a symbolic link and a shell script in /opt/bin
These are as follows:
/opt/bin/java

ln -s /opt/bin/jamvm /opt/bin/java

/opt/bin/javac

/opt/bin/jikes -classpath /opt/share/jamvm/classes.zip:/opt/share/classpath/glibj.zip $*

Remember to change the permissions on the shells scripts to add the execute flag!

I found out that there is also a  rxtxSerial ipk package which can be installed on the Synology. To do this just enter ipkg install  rxtx_2.1.7r2-1_arm.ipk on the command-line (you have to be logged in as root).

The cited post referred to this page.
Another page about Java and Synology is found here.

I’m wondering what is possible having all this installed (and what I need to install further). The code I tested uses URLConnection related classes and is not working yet … will be continued.

How to communicate using URLConnection in Java

Reading data with serial communication between Arduino and PC is one step. After the PC has received the data I want it to send the data (raw or after some calculations) to a website. The website will store the data and show the data in some nice graphs and tables.
The other way around I want to send some commands from the website to the PC where the Java app has to send it to the Arduino which on its turn will perform some actions. I will write another post on this subject some other time.

I found a nice page at Oracle describing how to use the Java URLConnection class.

Depending on the functionality of your website script/app you could start very simple with the code below.


import java.io.*;
import java.net.*;

public class Reverse {
    public static void main(String[] args) throws Exception {

	URL url = new URL("http://www.your-domain.nl/store_value.php?type=KAKU&value=1234567");
	URLConnection connection = url.openConnection();
	connection.setDoOutput(true);

	OutputStreamWriter out = new OutputStreamWriter(
                              connection.getOutputStream());
	out.close();

	BufferedReader in = new BufferedReader(
				new InputStreamReader(
				connection.getInputStream()));
	in.close();
    }
}

All we do here is opening an URL to a PHP page and provide it with two variables. These variables can be extracted from the URL by the PHP script. The snippet below shows a piece of PHP code to extract the variables from the URL. After you got the variable values they can be stored in a database, written to a file, etc..

<?php

$type = $_GET['type'];
$value = $_GET['value'];

// store it in a database or write it to a file or ...

print "TYPE = ".$type." -- VALUE =".$value."</BR>"; 

?>

I know it is very basic and not secure in the dangerous open network world (internet), but as a starting point for private network environments it might be helpful.

 

 

Serial communication between PC and Arduino

Using sensors together with the Arduino or JeeNode is cool. Using the serial monitor of the Arduino IDE lets you see the values. The data is sent from the Arduino over (in my case) a USB cable to my PC. With the serial monitor of the IDE I can receive and also send data.

To make a domotica solution I need something more than the serial monitor of the IDE. I want to be able to send and receive data from my own application and website.

I’m want to use Java to develop the application that’s going to send and receive data. Although I might also try C/C++ in a while, but for now I’ll focus on Java. The reason I want to use Java is that I’m using a Windows computer to develop, but I might want to use a Linux based device to let my application run and do its job. Hopefully it will be easier to switch between the two operating systems with an application written in Java.
(The platform I’m thinking of is the Raspberry Pi; hopefully soon to be ordered)

Searching for a good way to start writing code to communicate with an Arduino I found this page on the Arduino website and also another interesting website. (I did find this site about C and Arduino which might be useful in the future; and this one is I think about Processing and Arduino)

It turns out that by using the RXTX Java library it is possible to use serial communication to send and receive data between a PC and an Arduino. The page shows a code example of a Java app which is able to receive data from a serial port (COM port; in PC terms).

I chose Eclipse as my Java IDE (the SpringSource version to be exact). I had to download the 2.2pre version of the RXTX Library, because my Windows is a 65-bit version. In the 2.2pre package a 64-bit version of the rxtxSerial.dll is included. The 32-bit version will not work on a 64-bit OS, as I found out by trial-and-error. (I didn’t read through the entire page on Arduino.cc otherwise I would have seen the instruction)  Beware that when you use the 2.2pre .dll file you also need to use the 2.2pre RXTXcomm.jar file in your classpath. If you don’t a version mismatch error will be shown.

The steps I took for my basic serial communication test application were:

  1. copy the rxtxSerial.dll to c:\windows\sysWOW64
  2. add the c:\windows\sysWOW64 to your path
  3. added the location of the RXTXcomm.jar file to the classpath in Eclipse
  4. created a new Java project;
  5. added a new file to the \src of the project
  6. named it SerialTest.java
  7. copied the code snippet from the Arduino page (file is attached to this post)
  8. change the COM port to COM5
  9.  changed the bit-rate in the Java code (I needed 57600 for my JeeLink with RF12Demo)
  10. build en run

I saw the expected text from the RF12Demo in the console window of Eclipse.

The first step is done, data is transferred from JeeLink (Arduino) to a ‘self made’ application. The next step is, of course, to send data to an Arduino. I’ll let  you know whta my findings are.

The first of many steps to my own Java Domotica-bridge application.

BMP085 – Barometric Pressure Sensor

Want to keep track of the weather you  of course need the temperature which can be measured be using e.g. the TMP36. This is not enough we also need to know the barometric pressure to be able to do some weatherforecast. This pressure can be measured with  the BMP085 (datasheet); mounted on a breakout board (that can be found at Sparkfun) will be a good idea if you want to be able to connect it to your Arduino. An extra feature of the BMP085 is that it can also measure the temperature.

At Sparkfun you can find some useful links and Bildr has a nice example of how to connect the breakout board and get useful information from it.

It don’t have the BMP085 myself so I cannot tell you my experiences. I’ll write about it some time when I bought and installed one myself.

 

 

Is there light? LDR sensor input

You can imagine it is helpful to know when it gets dark in or around the house. Knowing this you could turn on the lights automatically.  There are different sensors you can use to measure light intensity. At the moment I have some LDR (light dependent resistor)  elements to do some tests.

An LDR has a  high resistance when no light is sensed, the resistance will decrease when the sensor is illuminated (see also).

A basic test scenario is to connect an LDR together with a 10K Ohm resistor to your Arduino.

Together with the code snippet below you can experiment with more or less light. I don’t know whether the printed values are close to reality but you can give it a try.

/* Photocell simple testing sketch.

Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground

For more information see www.ladyada.net/learn/sensors/cds.html
Modified by M.A. de Pablo. October 18, 2009.
Thanks to Grumpy_Mike for equations improvement.
*/


int photocellPin0 = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading0;     // the analog reading from the analog resistor divider
float Res0=10.0;		  // Resistance in the circuit of sensor 0 (KOhms)
// depending of the Resistance used, you could measure better at dark or at bright conditions.
// you could use a double circuit (using other LDR connected to analog pin 1) to have fun testing the sensors.
// Change the value of Res0 depending of what you use in the circuit

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);  
}


void loop(void) {
  photocellReading0 = analogRead(photocellPin0);   // Read the analogue pin
  float Vout0=photocellReading0*0.0048828125;	// calculate the voltage
  int lux0=500/(Res0*((5-Vout0)/Vout0));	     // calculate the Lux
  Serial.print("Luminosidad 0: ");		     // Print the measurement (in Lux units) in the screen
  Serial.print(lux0);
  Serial.print(" Lux\t");
  Serial.print("Voltage: ");			     // Print the calculated voltage returned to pin 0
  Serial.print(Vout0);
  Serial.print(" Volts\t");
  Serial.print("Output: ");
  Serial.print(photocellReading0);		   // Print the measured level at pin 0
  Serial.print("Ligth conditions: ");		// Print an approach to ligth conditions
  if (photocellReading0 < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading0 < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading0 < 500) {
    Serial.println(" - Light");
  } else if (photocellReading0 < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright");
  }
  delay(1000);
} 

Ladyada has a page with information about photocells, light, lux and Arduino. This page has a great sample scheme including a code example.

TMP36 – Temperature sensor

I picked the TMP36 (datasheet) to measure temperature. It’s a cheap and easy to use sensor with a broad range of temperatures it can measure. Several websites describe how to use it in combination with an Arduino, so it is easy to test it. In this post I use the information of several sources to describe how to use the TMP36. At the bottom I give the links to all sources.

The TMP36 can be used with voltages between 2.7V and 5.5V. The analog output lays between approx. 0V (ground) to 1.75V.

There are two formulas to calculate the voltages at the input pins,
one if you use 5V:

Voltage at pin in milliVolts = (reading from ADC) * (5000/1024)
This formula converts the number 0-1023 from the ADC into 0-5000mV (= 5V)

And one to use with  3.3V:

Voltage at pin in milliVolts = (reading from ADC) * (3300/1024)
This formula converts the number 0-1023 from the ADC into 0-3300mV (= 3.3V)

To convert the milliVolts to Centigrade use the formula:

Centigrade temperature = [(analog voltage in mV) – 500] / 10

Below is a code snippet that will ‘read’ the temperature in Centigrade.

/*  
*  Sample sketch to measure the temperature using a TMP36
*  The TMP36 is connected to 5V and analog pin 0
*/

// The Arduino pin the TMP36 signal pin is connected to
int tempPin = 0;    

void setup()
{
  Serial.begin(9600);  
}

void loop()
{
      //  Get the value from the sensor
      int readvalue = analogRead(tempPin);       
      float voltage = readvalue * 5.0;                     
      voltage = voltage / 1024.0;                    
      float centigrade = (voltage - 0.5) * 100 ;
      Serial.print(centigrade);
      delay(5000);
}

Ladyada.net descibes the sensor in this page.
Oomlout describes an example on its page.
Tronixstuff has also a description of how to use it.

To use the TMP36 with a JeeNode you can connect it:
TMP36 V+ (pin1) to JeeNode (+)
TMP36 Vout (pin2) to JeeNode Analog (A)
TMP36 GND (pin3) to JeeNode GND (G)

KAKU with Arduino using Nodo

The previous post was about JeeNode and receiving KAKU commands. The nodo-domotica  solution is also able to handle KAKU commands. I tried the Nodo sketch together with my Arduino Mega and an Aurel 433Mhz RX module bought from Conrad.

Aurel RX-4M50RR30SF

The module I used was the RX-4M50RR30SF (433mHz 5V – 102DBM – AM receiver). The productnumber at Conrad.nl is 190264 and it can be found here.

The Nodo schematic  shows that Arduino digital pin 2 is connected to the data-out pin of the RX module and that Arduino digital pin 12 is connected to the +5V pin of the RX module. The module’s GND pin is of course connected to a GND pin of the Arduino.
Looking at the photo above you see 8 pins instead of 3 pins; that’s because there is a pin for the antenna, 2 extra GND pins, a test pin (I don’t know how to use this) and an extra +5V pin. I connected all the three GND to the GND, the two +5V to pin 12 and the antenna pin to a approx. 17.5 cm piece of copper.
The nodo website mentions an antenna length of 15 cm but I already found some text about antenna lengths for 433Mhz signals mentioning the 17.5 cm. In close range both will work and that is what I have tested until now. It is also possible to buy a real antenna.

I was very happy to see this piece of hardware work. Before I tested this RF module I tried another module (QAM-RX4-433 from Ideetron.nl) which didn’t work in combination with the Nodo software.

 More things to sense …

 

JeeNode and OOK433 plug

Besides an Arduino Mega 2560 I can also use a JeeNode to do some experiments. The JeeNode is made based upon the Arduino but it has several differences. Like, it has fewer ports, it runs on 3.3V instead of 5V, it is smaller and has I2C support. Another great feature is the RFM12B wireless RF chipset that can be used to let JeeNodes communicate with eachother. Take a look at the JeeLabs blog for a ton of information, it is really great.

Because one of the wishes for my domotica solution is controlling KAKU devices a 433Mhz OOK RF receiver and transmitter is needed.  JeeLabs has a nice solution; the OOK 433 plug.

This plug has two 433 Mhz chipsets; one to send and one to receive signals. KAKU uses On-Off-keying (OOK) modulation for sending and receiving signals.

KAKU remote YCT-102

I assembled the plug and tested the ookDecoder.pde sketch (look at the bottom of the page), together with my KAKU YCT-102 remote. I was lucky as it worked right away; I read that some people weren’t able to get it working in combination with another KAKU remote (probably an older version).

It also works with the KAKU doorbell transmitter (ACDB-6500BC).

One thing to mention is that the sketch decodes the signals as ‘HEZ’ signals instead of ‘KAKU’ signals. Some other website also mentioned that the signals of the UCR-4285 universal KAKU remote were also recognized as ‘HEZ’ signals.

However, if you remove  ‘HezDecoder hez;’ in the ookDecoder.pde sketch the signals will show up as KAKU commands!

As for now I haven’t tried to send KAKU commands so I don’t know if that works in combination with my KAKU socket units.

Because I cannot find the webpage to download the ookDecoder.pde sketch I include it below. All credits go to Jean-Claude (owner of JeeLabs and creator of the JeeNode hardware) see the comments in the code.

 

// New code to decode OOK signals from weather sensors, etc.
// 2010-04-11 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: ookDecoder.pde 7527 2011-04-11 01:57:48Z jcw $

#include "decoders.h"

#define USE_433 1
#define USE_868 0

#if USE_433
OregonDecoder orsc;
CrestaDecoder cres;
KakuDecoder kaku;
XrfDecoder xrf;
HezDecoder hez;
#endif

#if USE_868
VisonicDecoder viso;
EMxDecoder emx;
KSxDecoder ksx;
FSxDecoder fsx;
#endif

#define PORT 1

volatile word pulse;

ISR(ANALOG_COMP_vect) {
    static word last;
    // determine the pulse length in microseconds, for either polarity
    pulse = micros() - last;
    last += pulse;
}

void reportSerial (const char* s, DecodeOOK& decoder) {
    byte pos;
    const byte* data = decoder.getData(pos);
    Serial.print(s);
    Serial.print(' ');
    for (byte i = 0; i < pos; ++i) {
        byte d = data[i];
        Serial.print(d & 0x0F, HEX);
        Serial.print(d >> 4, HEX);
    }
    // Serial.print(' ');
    // Serial.print(millis() / 1000);
    Serial.println();
    
    decoder.resetDecoder();
}

void setup () {
    Serial.begin(57600);
    Serial.println("\n[ookDecoder]");
    
    pinMode(13 + PORT, INPUT);  // use the AIO pin
    digitalWrite(13 + PORT, 1); // enable pull-up

    // use analog comparator to switch at 1.1V bandgap transition
    ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE);

    // set ADC mux to the proper port
    ADCSRA &= ~ bit(ADEN);
    ADCSRB |= bit(ACME);
    ADMUX = PORT - 1;
}

void loop () {
    cli();
    word p = pulse;
    pulse = 0;
    sei();

#if USE_433
    if (p != 0) {
        if (orsc.nextPulse(p))
            reportSerial("ORSC", orsc);        
        if (cres.nextPulse(p))
            reportSerial("CRES", cres);        
        if (kaku.nextPulse(p))
            reportSerial("KAKU", kaku);        
        if (xrf.nextPulse(p))
            reportSerial("XRF", xrf);        
        if (hez.nextPulse(p))
            reportSerial("HEZ", hez);        
    }
#endif

#if USE_868
    if (p != 0) {
        if (viso.nextPulse(p))
            reportSerial("VISO", viso);        
        if (emx.nextPulse(p))
            reportSerial("EMX", emx);        
        if (ksx.nextPulse(p))
            reportSerial("KSX", ksx);        
        if (fsx.nextPulse(p))
            reportSerial("FSX", fsx);        
    }
#endif
}

Nodo can do KAKU too …