Tuesday, May 31, 2016

Keep your house cool with ESP8266 #1.




Since the summer is near, yesterday were like 30 degrees Celsius, nothing is more comforting then coming home and have a nice temperature inside. 

But how to do that ? You can program your air conditioning AC to do that (if it has this function) but how about the days when you are not know at what time you will be home ?

It will be a lot of money that will be spend on electricity for nothing.

What if you will be able to control from your smart phone when to start the AC, what temperature to maintain, in which intervals everything with a cost of 5USD ?

Again for this project I am using the Witty module but  ESP-01 can do it  if you have one that you are not using it.


Witty module with IR LED and IR receiver


The schematics is very simple, below is one with 2 IR LEDs but you can use only one. An old remote control can be a good source of IR LED.



If you don't have R1 of 1K you can replace it with 680. The VCC I've used is 5V ( available on Witty module.

Parts list:
Witty ESP8266 module
Resistors - with 7USD you can buy 1400 pcs with all values (1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2, 10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82, 100, 120, 150, 180, 220, 270, 330, 390, 470, 560, 680, 820, 1K, 1.2K, 1.5K, 1.8K, 2.2K, 2.7K, 3.3K, 3.9K, 4.7K, 5.6K, 6.8K, 8.2K, 10K, 12K, 15K, 18K, 22K, 27K, 33K, 39K, 47K, 56K, 68K, 82K, 100K, 120K, 150K, 180K, 220K, 270K, 330K, 390K, 470K, 560K, 680K, 820K, 1M)
Transistor   2N2222 
IR LED or you can recover one from an old remote control

For capturing the signals from a remote control you can use:
IR Sensor module

For other project involving IR and ESP you can buy a remote control. and you will receive also an IR sensor and and IR LED.


Enough with the hardware, now lets go on the software.

Off course that my AC ( GREE model ) is not working with any standard protocol NEC, SONY, PANASONIC, LG, RC5, RC6 so a lot of work need to be done to make it work.


First  capturing the IR code sent by my AC remote using the IRremoteESP8266 library showed that it has an NEC encoding and 73 bytes. Playing the recorded 73 bytes with the 

void IRsend::sendRaw(unsigned int buf[], int len, int hz)

function didn't work. The IRremoteES8266 library has a standard buffer in IRremoteESP8266.h of 100 bytes.

#define RAWBUF 100 // Length of raw duration buffer


What if my data is bigger then that ? I've changed the value up to 512 bytes, but nothing,the AC was not responding to the raw data.

Ok then, may be the library is not recording the complete data sent be my remote, so a different approach was need it.


Let's record the data using the ISR.

1. Attaching the interrupt RX_PIN on function rxData with CHANGE ( both direction UP/DOWN)

attachInterrupt(RX_PIN, rxData, CHANGE);

2.Write the rxData function to record the time-stamp for any CHANGE in rx signal in a buffer.

void rxData()
{
buff[x] = micros();
x++;
}

3. After 3 seconds dump the data recorded in the buff[] decreasing the two consecutive values. At the end will have just the time difference between any consecutive CHANGE in signals.




Wow ! The length of data is bigger now (139 vs 73 bytes)



unsigned int buff[73] = {9000,4500, 650,1650, 650,600, 650,600, 650,1700, 650,600, 650,600, 650,600, 650,600, 650,1700, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,600, 650,1650, 650,1650, 650,600, 650,600, 650,600, 650,600, 650,600, 650,1650, 650,600, 650,1700, 650,600, 650,600, 650,1700, 650,600, 650};


versus

unsigned int buff[139] = {9050,4500, 800,1600, 750,550, 700,550, 700,1600, 750,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,1600, 750,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,1600, 750,1600, 750,550, 700,550, 700,550, 700,550, 700,550, 700,1600, 750,550, 700,1600, 750,550, 700,550, 700,1600, 750,550, 700,19950, 750,500, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,1600, 750,550, 700,550, 750,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,550, 700,1550, 800,550, 750,500, 700,1600, 750};


EUREKA ! sending the new captured data start the AC !!!

Now lets see what is different between those two data sets. In the middle of the 139 buffer I can see that there is a big value of 19950 (in usec => 19.95 ms) and the data after, looks almost the same for each command. That's the catch!!!

Full data received will be like this:



Timing[139]: 
     +9050, -4450     + 800, -1600     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, -1650
     + 800, - 500     + 700, -1650     + 800, - 500     + 700, -1650
     + 800, - 500     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 600     + 750, - 500     + 700, -1650     + 800, -1550
     + 800, - 500     + 700, - 550     + 700, - 550     + 750, - 500
     + 700, - 550     + 700, -1650     + 800, - 500     + 700, -1650
     + 800, - 500     + 700, - 550     + 700, -1650     + 800, - 500
     + 700, -19900    + 800, -1600     + 800, - 500     + 700, - 550
     + 700, - 550     + 700, -1650     + 800, - 500     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, -1650     + 800, - 500
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, - 550     + 700, - 550     + 700, - 550
     + 700, - 550     + 700, -1650     + 800, -1550     + 800, - 500
     + 700, - 550     + 700

Where 9050 (9ms )and 4450 (4,5ms) are the header. After removing the header you see a
lot of +value and -value. Observing them can jump to the conclusion that after removing all the +values the rest will be 0 (~700+/-200) and 1 (~1600+/-200). Counting the number of bits from the beginning and from the end will result in 32 + 3 + 32 where the middle 3 bits are just before the -19000 (19ms) value and are always 010(b).

Header: 9000
Header space: 4500

Logic "0" 0: 600
Logic "0" 1" 600 ====> +700 -550 is coresponding a "0" logic

Logic "1" 0: 600
Logic "1" 1: 1650 ====>+700 -1690 is coresponding an "1" logic

Now looks like the protocol is 35 bits followed by 32 bits. So for turning on the AC with value of 20 degrees will have 0x9220060A 101(b) 0x8804004.

I see that the last digit (4) from 0x8804004 is changing based on the temperature and the command (on/off) so, can be a kind of CRC.

Other codes (until the 19950) decoded as NEC protocol.

Temp / Data
16 0x9000060A;
17 0x9080060A;
18 0x9040060A;
19 0x90C0060A;
20 0x9020060A;
21 0x90A0060A;
22 0x9060060A;
23 0x90E0060A;
24 0x9010060A;
25 0x9090060A;
26 0x9050060A;
27 0x90D0060A;
28 0x9030060A;
29 0x90B0060A;
30 0x9070060A;



Changing third byte is changing the temperature. Other bytes are for cool/dry/heat/fan/auto for fan power or swing option etc.

Now I need to add the regular MQTT and WiFi code like in this post, change the mobile app to accommodate the new module and I will be able to set up the temperature in my house from my mobile.

Unfortunately there is no feedback to check that the ON command was received by your AC device, but an accelerometer can be attached to sense the vibrations of your AC ( in this case the unit need to be put on top of your AC) or a temperature sensor can be place in front of your AC and monitor air temperature provided by your AC unit.



If you have more AC units in your house you can build more modules and add more sensors to them (temperature, vibration to check that the unit is working etc).




Wednesday, May 25, 2016

Decoding a LoraWAN payload send by your ESP8266 gateway



If you are receiving a LoraWAN packet on you LoraWAN gateway using the ESP8266 module most probably  you will forward it to a back-end server to be processed by your application. But the message is encoded and encrypted so this is the procedure to do it right.


rxpk update: {"rxpk":[{"tmst":1060664170,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":12,"rssi":-28,"size":31,"data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig=="}]}




Step1. Base64

The "data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig==" need to be decoded using base64 and the result will be:

64, 98, 7, -32, 2, 0, -86, 0, 1, -68, -109, 85, 23, -128, -23, 81, -86, 105, -1, 20, 13, -43, 17, 21, -100, -113, -93, 98, -124, 122, 34





Step 2. Build the block A(i) according to the 4.3.3.1 

For each data message, the algorithm defines a sequence of Blocks Ai  for i = 1..k 
with k = ceil(len(pld) / 16). In our case the k=2 because the len(pld)=31 so there are 2 blocks that need to be constructed.

An A Block will be like this one:

-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x01



-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x02


Where Dir is direction and it is 0 for uplink and 1 for downlink



Step 3. Encrypt each A Block

The blocks Ai are encrypted to get a sequence S of blocks S(i) :  S(i) = aes128_encrypt(K, Ai) for i = 1..k

So, on this step each A block will be encrypted ( yes encrypted !!!) AES128 with the same
key used on node side. 

A ciphertext will be like:

c7b11d72ec853e8853dd4362a77d71ad



Step 4. XOR the cipher with payload.

S = S1 | S2 | .. | Sk

Don't forget that encryption and decryption of the payload is done by truncating (pld | pad16) XOR S to the first len(pld) octets.


At the end the text {"Hello":"World1"} will be available for your application. If at the node side this text is encrypted your app will need to do a decryption to get it.





Tuesday, May 24, 2016

Node MCU - ESP8266 pins corespondence


This is not to search every time I need it !!!

Correspondence pins between NodeMCU and other ESP8266 modules.

File pins_arduino.h

static const uint8_t SDA = 4;
static const uint8_t SCL = 5;

static const uint8_t LED_BUILTIN = 16;
static const uint8_t BUILTIN_LED = 16;


NodeMcuESP8266
D0GPIO 16
D1GPIO 5
D2GPIO 4
D3GPIO 0
D4GPIO 2
D5GPIO 14
D6GPIO 12
D7GPIO 13
D8GPIO 15
D9GPIO 3
D10GPIO 1


A better image:

http://www.banggood.com/Geekcreit-Doit-NodeMcu-Lua-ESP8266-ESP-12E-WIFI-Development-Board-p-985891.html?p=630301435985201402N9


Wednesday, May 18, 2016

Esp8266 meets LoRaWan

I guess that you don't have any doubts that ESP8266 can do LoRaWan.

For this project I've used two modules:

1.LoRaWan Single Channel Gateway

Single channel gateway ( to be compatible with LoRaWan you must have 8 channes) was made using the SX1276 module and a Raspberry Pi2. Comunication is done over SPI using wiringPi library.


Single channel gateway


2.LoRaWan node with ESP8266 

For node I've used the Witty module with the modifications from this post.
As a software I've used the ported LMICv1.51 and modified to send data to only one channel since the gateway is single channel ( I am using 868.1Mhz).


Lora Node with ESP8266

Now the gateway is enrolled in TTN ( https://thethingsnetwork.org/) and the data has started to arrive. I've managed to receive also data from other surrounding nodes.


On the gateway data looks like:



Packet RSSI: -107, RSSI: -105, SNR: -11, Length: 108

rxpk update: {"rxpk":[{"tmst":368384825,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":-11,"rssi":-107,"size":108,"data":"Wqish6GVYpKy6o9WFHingeTJ1oh+ABc8iALBvwz44yxZP+BKDocaC5VQT5Y6dDdUaBILVjRMz0Ynzow1U/Kkts9AoZh3Ja3DX+DyY27exB+BKpSx2rXJ2vs9svm/EKYIsPF0RG1E+7lBYaD9"}]}


and data from my nodes:

Packet RSSI: -28, RSSI: -105, SNR: 12, Length: 31

rxpk update: {"rxpk":[{"tmst":1060664170,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":12,"rssi":-28,"size":31,"data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig=="}]}


Next I'll have to add sensors to nodes and to run some tests for range and buy a real gateway.

More info about LMIC port and code here.




About LoRa and LoRaWan

LoRa is based on opened radio-frequency communications, different frequencies are used depend on locations:
  • 430 Mhz – valid for Asia
  • 780 Mhz – valid for China
  • 433 Mhz – valid for Europe
  • 866 Mhz – valid for Europe
  • 915 Mhz – valid for USA
LoRa supports different Data Rates and offer a large radio link budget over 160dB. The power consumption is about 40mA during transmission and 10mA during reception. It allows a wide coverage : about 2.5Km from antenna inside a city and up to 15km in a countryside.
LoRa is based on a Spead Spectrum technology this technology helps to reach long distance over noise boosting up to 10x the distances obtains with classical transmission systems. It also have a good shifting frequency immunity.  LoRa sound to have good results on movement. It uses wide-band linear frequency modulated pulses. Frequency increase or decrease to encode the information.

LoRaWAN Classes, © 2015 LoRa™ Alliance.

LoRaWAN™ is a Low Power Wide Area Network (LPWAN) specification intended for wireless battery operated Things in regional, national or global network. LoRaWAN target key requirements of internet of things such as secure bi-directional communication, mobility and localization services. This standard will provide seamless interoperability among smart Things without the need of complex local installations and gives back the freedom to the user, developer, businesses enabling the roll out of Internet of Things.
LoRaWAN network architecture is typically laid out in a star-of-stars topology in which gateways is a transparent bridge relaying messages between end-devices and a central network server in the backend. Gateways are connected to the network server via standard IP connections while end-devices use single-hop wireless communication to one or many gateways. All end-point communication is generally bi-directional, but also supports operation such as multicast enabling software upgrade over the air or other mass distribution messages to reduce the on air communication time.
Communication between end-devices and gateways is spread out on different frequency channels and data rates. The selection of the data rate is a trade-off between communication range and message duration. Due to the spread spectrum technology, communications with different data rates do not interfere with each other and create a set of "virtual" channels increasing the capacity of the gateway. LoRaWAN data rates range from 0.3 kbps to 50 kbps. To maximize both battery life of the end-devices and overall network capacity, the LoRaWAN network server is managing the data rate and RF output for each end-device individually by means of an adaptive data rate (ADR) scheme.
National wide networks targeting internet of things such as critical infrastructure, confidential personal data or critical functions for the society has a special need for secure communication. This has been solved by several layer of encryption:
  • Unique Network key (EUI64) and ensure security on network level
  • Unique Application key (EUI64) ensure end to end security on application level
  • Device specific key (EUI128)
LoRaWAN has several different classes of end-point devices to address the different needs reflected in the wide range of applications:
  • Bi-directional end-devices (Class A): End-devices of Class A allow for bi-directional communications whereby each end-device's uplink transmission is followed by two short downlink receive windows. The transmission slot scheduled by the end-device is based on its own communication needs with a small variation based on a random time basis (ALOHA-type of protocol). This Class A operation is the lowest power end-device system for applications that only require downlink communication from the server shortly after the end-device has sent an uplink transmission. Downlink communications from the server at any other time will have to wait until the next scheduled uplink.
  • Bi-directional end-devices with scheduled receive slots (Class B): In addition to the Class A random receive windows, Class B devices open extra receive windows at scheduled times. In order for the End-device to open its receive window at the scheduled time it receives a time synchronized Beacon from the gateway. This allows the server to know when the end-device is listening.
  • Bi-directional end-devices with maximal receive slots (Class C): End-devices of Class C have nearly continuously open receive windows, only closed when transmitting. Class C
[Text from https://www.lora-alliance.org/What-Is-LoRa/Technology]

More details about the protocol can be found in the document.