Sunday, January 26, 2014

From remote vacuum cleaner to my weather station

Story started quite differently than you may expect.
My initial plan was not to play with my weather station, but with remote control to my vacuum cleaner :) I have Miele brand vacuum cleaner with remote control buttons located on gripping part of pipe where you usually hold cleaning pipe.

I was trying to reverse engineer that. There were no markings on device about its working frequency so I use cheap DVB-T dongle supported by rtl_sdr libray as my spectrum analyzer and GNU Radio as a frontend. First step is of course to find working frequency. I assumed that it will work on 433MHz or 868MHz or 2.4GHz band. That was easy - I spotted nice signal on 433.82Mhz My initial step was to discover modulation used by this device.

Since this is only home appliance I was not expecting QAM256 :) I focused on trying to get some bit stream by experimenting with ASK,FSK,GMSK. I started with ASK and that was first good shot. In fact my vacum cleaner is using OOK (On Off Keying) modulation which is extreme type of ASK where you switch on/off carrier.

By using GNU Radio FFT and Scope sink with low pass filter I saw that I have regular pulses of something what was interferences from my perspective. You can see this as decaying line close to the right of main signal. It is hard to catch < 1 s pulse..
I knew that this must be some other devices in my vicinity. Since pulses were rare this must be something energy efficient. My first suspects were SMART Water meter with radio transmitter or heat logger mounted on my water powered heaters. Both are made by Ista and have radio interface. They are waiting for my free time to start hacking them :) After some walking over my house with laptop and DVB-T dongle I ruled out both of them, and then I remembered about my weather station since signal was strongest near part of house where it was located.

Some time ago I bought cheap 30 PLN (~7,5 EURO) weather station in Biedronka shop. For those who are not familiar with this name it is a shop network directly competing with Lidl on Polish market. They sell mostly grocery but they have some home cheap china electronic stuff also. Quality is mostly crap but you can find some rare oportunieties..


Remote unit model part number is WS-9941-M. As you can see there is a mark that it is working on  433 MHz band. Clearly it was my source of interference. Unfortunatelly I'm still learning GNURadio and I was able to see data on screen however I was unable to make setup to dump this data to file. I went to my neighbor radio shack shop AVT. It is really neat to have such well stocked electronics shop just 10 minutes bike drive. I bought  ZS-RR10-433MHZ  433.92 MHz radio reciever for 20 PLN (~5 EURO). This is really neat device - you just plug in to power, put some antena and you get demodulated signal on one of the pins.
After connecting Salae Logic Analyzer look what I got:



As you can see there is clearly pattern here. First what you see is sync packet contains three pulses and then delay ~ 9ms.  Then is pattern repeated 10 times. We have pattern here but what exacly "0" and "1" are represented ?


I search web page for any similar devices. Unfortunately there is not many such pages. I found Fred's webpage, and rc-switch Arduino library. I looked into source files and none protocol was similar to mine.

I dumped data from Salae to CSV file and started  write some python stuff that will try to get something from those data.
As you can see this signal have constant high pulse time so no duty modulation was possible. Period is changing and this was the clue. Like in every reverse hack you must start with some assumptions and check if they are wrong or not. I made one that bits are coded with time distance between two rising edges or two falling edges (since high state period is constant). With such assumption and data in csv file i wrote simple python code that will check time between two rising edges and if one is smaller than <VALUE_0> it is one bit, and second time period <VALUE_1> is zero bit. Of course you need some samples with knowledge what is expected to be inside, so I dumped packets for different temperature readings  on my weather display and this is what I got
Temperature (Celsius)Data
18,8 C101001101000000010111100111100000000
20,1 C101001101000000011001001111100000000
20,7 C101001101000000011010000111100000000
Definitely I have data here :) Encoding method assumption seems to be OK. First notice is weird data packet length - 36 Bits. I tought that my encoding is wrong, checked one manually. No errors. Some bits were never changed so I removed them for further analysis and focused on the ones which are changing. My another assumption - data should be contained or aligned within N x bytes. Yeah - maybe this cheap chinese stuff have 4bit MCU ..but lets start with some normal assumptions :) I converted this to decimal format and this is what I got:

Temperature (Celsius)Data
18,8 C188
20,1 C201
20,7 C207

Since such chip devices shouldn't be very efficient with float operations and temperature resolution was 0.1 deg I expected that station will multiply temp value by 10 and this should be value - and assumption was right.

I was happy and started to check my script until i measured first negative temperature. Since we have nice winter in Poland I put weather transmitter outside where it should be and started measurement. It was < -13 C deg and going down. Results were at least weird. Here is what I got with my previous method:
Temperature (Celsius)DataData decimal
-14.1 C101001101000111101110011111100000000115
-14.2 C101001101000111101110010111100000000114
-14.5 C101001101000111101101111111100000000111

I noticed that encoded number is going down along with temperature drop. So what is minimum temperature device can measure so all bits will be zeroes ? Simple extrapolation and result is -25,6 C deg. Now this is very nice and special number for binary system :) So 0 deg will be 256 or "11111111". Simple math and we have formula for negative temperature schema:

Negative TEMP = ( VALUE - 256)/10

Where is "-" mark ? The only difference between negative and positive data are next 4  most significant bits you see on bold in table.

This is python based algorythm for decoding my wireless station data:
def decode(data):
    # convert 36 bits to long integer
    value=int(data,2)
    # remove 12 least significant bits by shifting >> 12
    value=value >> 12
    # remove preambule - only 12 least significant bits are important
    # 0xfff is in binary 111111111111. All other bits will be ignored
    value=value & 0xfff
    # lets check do we have negative temperature by comparing bits 10-12
    # 0xf00 is 111100000000. We are checking value of 3 most significant bits
    # if set to 111 - negative temp. If set 000 - positive
    if (value & 0xe00) == 0xe00:
        # Negative algorythm
        return ((value & 0xff) - 256) / 10.0
    else:
        # Positive temp algorythm
        return (value & 0x1ff)/10.0

Now it is time to make some hardware to receive data from my unit and put them to PC via USB/UART, and put my temp data public. I have some STM32, PIC32, KL25Z,Atmega MCU's laying arround. But this is story for next part.

Update:
Jakub mention in comments that maybe my assuption about positive values is not perfect because that would mean max + temperature is 25.6 C deg. He was right. This is perfect example of working with not sufficient data samples :)
In fact temperature is encoded (probably)  in 12 bits signed format. I tested only up to ~ 40 C deg by warm up sensor above 25,6 C deg. In order to check if bits 10 and 11 also containg temp data I would have to warm up device above 51.2 C deg. :-)  Maximum temperature with 9 bits  would be 51,2 C deg and this comply with sensor range from specification  which is -25 - +50 C de, and I don't need higher values so example above decodes just 9 bits.
I updated python code  

Monday, April 23, 2012

PKP

Dzisiaj trochę rantu na naszym rodzimym koniu do bicia - PKP.
Pociągami jeżdzę sporadycznie i niewiele się w tym temacie zmienia. Są jednak pozytywy.
Ostatnio jechałem EIC do Poznania i byłem bardzo pozytywnie zaskoczony jakością taboru. Czysto, klimatyzacja, gniazdka 230V, bar w pociągu - normalnie żyć nie umierać.
Z technicznego punktu widzenia jedyne co przypomina stare składy to skrzeczący jak przez stary radiowęzeł personel pociągu informujący o stacjach, podróży itp.

Jeśli chodzi o organizację nadal tragedia :(. Jechałem z kolegą, który miał bilet kupiony normalnie w okienku, ja zaś jako nowoczesny podróżny miałem kupiony on-line.
Przy powrocie z Poznania okazało się, że zdążymy na wcześniejszy pociag (też EIC) dzięki czemu będę 2h wcześniej w domu. Jak się okazało konduktor bez problemu może zabrać mojego kolegę z normalnym biletem wcześniejszym pociagiem i wystawić miejscówkę. Ja za to mam jakiś magiczny bilet, który jest niezmienialny i musiałem czekać 2h lub wydać 130 PLN na nowy bilet. Jak widać w PKP bycie nowoczesnym się nie opłaca.

Drogie PKP - jak już coś robicie (sprzedaż on-line) - nie róbcie z ludzi, którzy wam oszczędzają i czas i kolejki przy kasach pasażerów drugiej kategorii.

Monday, February 20, 2012

Analizator antenowy w/g VK5JST i problem Ohma

Postanowiłem sobie zbudować analizator antenowy w/g koncepcji VK5JST z rozszerzeniami kolegi SP2JJH. Wszystko udało się bez większych problemów, analizator ruszył od pierwszego włączenia. Niestety wszystko psuła jedna mała "rzecz". Na żadnym posiadamym przeze mnie wyświetlaczu nie wyświetlał się prawidłowo symbol Ohma czyli litera Omega.
Pewnie owe chińskie produkty mają inną tablicę kodową, gdyż zdecydowanie był to ichni krzaczek :)

Zajmuje się hobbystycznie też programowaniem mikrokontrolerów, ale jak dotąd nie miałem okazji bawić się PIC'ami a tylko AVR'ami, MSP430 oraz procesorami ARM Cortex-M0. Analizując z pomocą Arduino co tam mają pod adresem 0xF4, którego używa oryginalny program w każdym LCD jaki miałem był ten sam "krzaczor". Ponieważ chciałem aby rozwiązanie było przenośne postanowiłem wykorzystać dostepną pamięć CGRAM. Wycieczka do AVT po programator PIC i zacząłem zabawę.

Każdy wyświetlacz ma  pierwsze 8 rejestrów dostepnych jako zapisywalne przez użytkownika dla jego własnych symboli. Co do szczegółów odsyłam do Wikipedii gdzie jest szczegółowy opis sterownika HD44780.

Największym problemem okazało się skonfigurowanie środowiska MPLAB 8 z kompilatorem CC5X używanym przez VK5JST. Dwie godziny potem środowisko było gotowe i kompilator prawidłogo kompilował oryginalny kod.
Cała reszta to przyjemność programowania :) Co mi się podoba w MPLAB i CC5X:

  • Jeśli wcześniej zadeklarujemy małe makro  np: pragma bit LED_0 @ PORTB.0 to potem zmiana stanu tego portu to poprostu LED_0=1 ! Żadnych &= ~() czy |= na całym rejestrze. Bardzo przyjemna i czytelna sprawa.
  • Pomimo "dziwnego" interfejsu MPLAB 8 - bardzo szybko można zacząć pracować bez dziesiątek wizardów, innych utrudniaczy, czy importowania dziesiątek bibliotek.
A jak wyglądają owe zmiany. Tutaj znajdziecie źródła z moimi poprawkami oraz plikiem wsadowym hex do PIC'a ant-anl-0.04.zip. Napisałem do Vadima, więc może niedługo znajdzie się to w oficjalnym kodzie.
Dla tych co nie chcą dłubać przez cały kod:
  1. Deklaracja tablicy zawierającej opis graficzny litery Omega w pliku lcd_nmix.c
    const char ohm[8] ={0b00000,0b00000,0b01110,0b10001,0b10001,0b01010,0b11011,0b00000};
    
    Każdy bajt opisuje jakie pixele mają być włączone dla każdej z 8 poziomych linii znaku graficznego 5x8 pixeli. Tak więc znaczenia ma tylko pierwsze 5 bitów.
  2. Kod zapisujący znak Omega do pamięci CGRAM w lcd_nmix.c:
    void lcd_add_ohm(void)
    {
    LCD_RS=0;
    lcd_write(0x40);
    LCD_RS=1;
    delay_us(40);
    // send ohm character
    for(k=0;k<8;k++) { lcd_write(ohm[k]);}
    //switch back to DRAM
    LCD_RS=0;
    cd_write(0x80);
    LCD_RS=1;
    delay_us(40);
    
  3. Wywołanie powyższej funkcji w inicjacji wyświetlacza lcd_init(void) w lcd_nmix.c
  4. Zmiana adresu z pod jakiego brać symbol Ohma w aa_defs.h:
    #define LCD_OHM 0x00
I to wszystko. Tak więc programowanie PIC'ów nie takie straszne i w sumie poza drobnymi niuansami różnic pomiędzy 8-bitowcami nie ma.


Monday, March 21, 2011

Eco server iConnect - part 1. A little of soldering.

As I mentioned in my fist post here is first part of my story how I made eco server out of Iomega iConnect.
Before making server out of iConnect you have to get serial access to uboot and console. Without that you just have black box :)
iConnect have internal UART 3.3V interface inside. Iomega was kind enough to not desoldering pins and serial console is ready to connect wires :)
Since having serial console outside your device will be very usefull I made external connection using 3.5mm stereo jack. Here is photo of my console external permement connection:

In order to make such setup i used:
  • 3.5 mm stereo jack socket
  • 3.5" floppy drive power connector
Floppy (for those who don't know what it is - here is explanation) power cable have the same pin raster like iConnect connector so it will fit perfectly. I removed on of wires from floppy cable since RS is using only 3 (RX,TX,GND) and moved color cables in original floppy cable between positions so black is GND, yellow is TX and red is RX.
I decided to place jack near RJ-45 socket since this is the only place where is enough space to make such output and it was safe to drill hole without removeing front panel. Please be carefull when making hole for jack socket - hole will be close to PCB - if your drill will "touch" board you can brick your device.
After that you can solder wires from floppy connector and jack.  Her is pinout specification:

And here is how this looks from front panel when device is closed:

Now I have access to serial at any time. Last think you need is rs-232 <-> UART 3.3 V converter and simple cable jack<-> RS-232. Do not connect iConnect serial port directly to your PC RS-232 port ! You need  voltage converter  for example one based on MAX232 intergrated circuit. Schematic how to use it you can find here (page 17) or if you need only schamatic that I used first it is this picture. If you want something more I prefer to use USB-TTL converter based on FT232RL. This one I just connect to PC USB and other side to my device. This is one made by myself (PCB bought in internet):

Now I have full console access to my iConnect on every PC and I started fun with software installation. This will be described in my next post.

Sunday, March 20, 2011

iomega iconnect as eco server

I'm sysadmin for many years and I had always my "private" server. My last one in my home was Epia VIA600 Mhz based powered by FreeBSD. Unfortunatelly after my father visit who accidently remove power cord using his foot (still don't know what he was doing behind my desk :) ) board was gone.

I decided to build new one, but this time I was looking for something more eco-friendly and less noisy since my "home server" is in my main room (technical wire obstacles). After some digging I found SheevaPlug. That was almost perfect. Only problem is that it is not avialable in Poland and I had realy bad experience with Polish Post Office, so buying it outside Poland was last resort.

Then I found this (http://www.plugapps.com/index.php5/Portal:Hardware) webpage. Segate Dockstar and Iomega iConnect are avialable in Poland :) I choose iConnect because it have 802.11n WiFi card (ralink RT3090) and more RAM (256MB). I was afraid that install might be problematic because there is not many webpages discussing Linux installation on iConnect but I was open to try.

I had some experience with embedded hardware in past so that was not so hard, however there are some issues I would like to share with you on my next post about Debian installation on iConnect.

Followers