Thursday, November 5, 2015

AUX in Volvo HU-XXXX radio

This post is a description/tutorial on how I managed to hack the stereo (HU-650) in my Volvo V70 (2007) and successfully added my own AUX input. This hack should work with any HU-xxxx unit, "HU" meaning Head Unit (the stereo)



Background

Why, why, why isn't there an AUX input on my car stereo from 2007?
Yes 2007 was before the big era of smartphones, but everyone owned a couple of dirt cheap mp3 players and  iPod was a big thing.

The HU that my car is fitted with has two super retro 8-pin DIN-connections on the back. One of which is for connecting a CD-changer "CD-CHGR" that you could have installed in the boot of the car - but who uses CDs these days?

It didn't take allot of research to find out there is already a product out there that lets you add an AUX to you HU-xxxx. The only drawback is that it sets you back $80 and most of all: It doesn't come with the awesome feeling that you get when you have hacked the stereo yourself.

Research

It wasn't an easy thing finding information on how to hack the HU, but after allot of research I finally found some really good pages that made the hack easy peasy.

This is how it works:

  • The source knob on the HU lacks the ability to choose the CD-CHGR until you connect the CD-changer. 
  • To trick the HU that you have a connected a CD-CHGR is not as easy as to shorten two of the pins on the DIN-connector, but it has to be done in code via a protocol named MELBUS
  • MELBUS is a protocol that utilizes a clock pin and a single bi directional data line to transfer the data between the units and the HU.
  • MELBUS uses three lines: Clock, Data and Busy see blue lines on picture below: ("Run" is just 12V from battery)
Picture source
  • In the picture above you can also see the Left and Right Audio signals that I tapped into for the AUX-input (Red). 
  • Focus on the left DIN-Socket (female) on the picture, that's the back female socket on the HU. 

Hardware


Total cost: ~$3.5

Hacking together some code

Edit 2016-11-04
A guy named Sebastian has modified my code and his version is more stable, and it also works on Mitsubishi HU and supports displaying track numbers! -Here's a link to his code!

Finally some programming! 
I found this awesome write-up that contained almost everything I needed to fool the HU that the Arduino is a CD-CHGR. I will talk you through the process:
  1. Set BUSY to low for 1000 ms to make the HU run its initialization routine
    1. The HU init routine starts by sending three bytes: 0x07 0x1A 0xEE
    2. Then two bytes per optional connection device (~30 of them), the first byte being the predefined ID of the device (ex. CD-CHGR = 0x8E), followed by either an empty byte 0xFF, if the device is not connected, or the answering ID of the device (CD-CHGR = 0xEE)

      Example: External CD-CHGR: ID = 0x8E and its return ID is 0xEE
      Example: Internal CD-player: ID = 0x80 and its return ID is 0x86
      See list of predefined addresses and returns on bottom of this site. 
    3. I.e. to simulate a connected CD-CHGR we have to: 
      1. Trigger the HU init routine
      2. Wait until HU is sending out our ID (0x8E)
      3. Respond to that by sending back 0xEE 
  2. Now the HU has registered that we have a CD-CHGR and it is now available through the source-knob, and will listen to the Left and Right Audio pins on the DIN-plug. 
  3. Every time the car ignition is turned on, the HU will automatically run a secondary initialization routine:
    1. Starting by sending four bytes: 0x00 0x00 0x1C 0xED 
    2. Then two bytes per already registered connection devices from the first init routine, the two bytes follows the same pattern as in the first init routine, first ID, than expecting the same answering byte as before.
    3. If the HU won't get an answer from the CD-CHGR, the device will be removed, and we have to set BUSY low again to call the first init-routine.  
That's it for fooling the HU that the CD-CHGR is connected, now it's just a matter of connecting a device to the Left and Right Audio pins plus Ground. I soldered a network cable plus an 3.5 mm Audio cable to the pins of a DIN-plug.

Take care when reading the schematics above, it is the left socket on the picture you are interested in, that's the socket on the back of the HU-unit (female) and will be equal to the back of the DIN-plug.  (as you can see, I put the red cable on the "RUN" to use the 12V to power the arduino, White and yellow are Audio Left and Right)
As a bonus the 12V is only active when the ignition is turned on => no extra load on battery caused by the arduino when car is not used)



The code I wrote (below) is well documented and fairly easy to understand...

I had a hard time getting the function "SendByteToMelbus(uint8_t byteToSend)" to work.
It turned out that the Arduino functions: digitalWrite(MELBUS_DATA, HIGH); and LOW are too slow for this code, (MELBUS runs at 10-12MHz) and CLK had returned to high state before Databit was changed.

To solve this, I had to go back to the old AVR-GCC technique and use
PORTD |= (1<<MELBUS_DATA); and
PORTD &= ~(1<<MELBUS_DATA);
in place of the Arduino functions.

I tried this setup without any form of ground-loop isolation and it works like a charm! Even when the engine is running and my smartphone is charging through the cigaret-socket the sound is crisp and no disturbing noise (alternator suppose to cause ground noise)

I guess one could buy an external Ground Loop Isolator ($5) to be on the safe side....










Sunday, November 23, 2014

Power Plug Energy Meter - Now wireless!

This is the second post about my work on the cheap China-style energy meter hack.
My last post covered how I with a logic analyzer successfully (but not in the safest way) sniffed the SPI-transmission on the device and managed to decipher the data. And then how I used an Arduino Nano to do the sniffing for me with an interrupt driven approach. The Arduino  translated the bits and bytes to power and voltage values that it continuously printed on the PC's Serial monitor via an USB-cable.

The next obvious step in this project is to get the energy meter to transmit the data wirelessly. Not only would this mean that I could grab data from several energy meters simultaneously, but it also creates a safe way of debugging the device since my previous setup (which I abandoned after reading some of the comments on Hackaday.com) meant connecting the mains neutral to the computers ground (do not try this at home!!!)

Today's post will cover how I managed to get an Arduino pro mini (3.3V) to sniff the energy meters SPI and transmit the data wirelessly with a nRF24L01+ to an Arduino Nano connected to a computer. The neat thing with this setup is that the Arduino pro mini and the nRF fits perfectly within the casing of the energy meter, and are both driven by the internal power that charges the rechargeable battery that you'll find in the meter.


The total cost of components for each energy meter is:
Energy meter             £7.97
Arduino Mini 3.3 V       £2.58
nRF24L01+                 £0.99   (choose the black + version)
A capacitor + cables   pretty much free, say £1

which comes to a total of £12.54 per unit!

Plus one computer connected node, or a raspberry pi with a nRF24L01 to receive the transmissions from all the energy meters.

Arduino and RF24.h
As mentioned in previous blog-posts I have worked quite allot with the nRF24L01 and AVR's, writing my own libraries and so on. But since this is my first Arduino-project I wanted to learn how to import and use other peoples libraries. Since I am still a newbie in programming, I always have to learn everything from scratch, and nothing ever works as supposed to when I try to follow a tutorial...


I started out by setting up two Arduino Nanos according to this guide and running the example code at the bottom of that page, and as expected - it didn't work. 



Debugging
1. Do I have a working SPI-connection?
I had followed the explanation in the guide i linked to above, on how to install the RF24.h-library and it all seamed to work, I definitely had a working SPI-connection between the Arduino and the nRF since I could print out all the registers, and modifying them also worked...

Took me a while to figure out that I had to download and include the file "printf.h" and call "printf_begin();" to print out data from the nRF to the serial monitor... and why, why, why are they using the "protected" attribute  for many of the functions??? For example get_status is a very useful debug-function and should not be protected!

2. Am I using the correct hardware setup? 
As always I hadn't used the exact components as the instructions said, in my drawer I could only find one 47 uF 24 V  and one 100 uF 16 V capacitors. Well in the guide it sais:
"Connect a .3.3 uF to 10 uF (MicroFarad) capacitor directly on the module from +3.3V to Gnd (Watch + and - !) [Some users say 10 uF or more..]"
And I read 10 uF or more....

Anyways, I thought that this should work, since I have used these capacitors before on the nRF, but not with this library and not with Arduino...

3. I found a working code
Yay, suddenly i found a working code, the "pingpair" example that comes with the NRF.h-library worked with my setup!

4. Why does only Pingpair-code work? 
I started stripping the Pingpair-code of its components, and found that my setup was only working when it got into receiving mode in between every transmission... strange, but keeping in mind that I was using bigger capacitors I figured it had something to do with the capacitors not have time enough to recharge/discharge.

I think this is what happened:
When the Arduino calls the "Write" function, the library runs the "startWrite"-function which powers up the nRF and has a predefined delay of 150 us (wait for the nRF to power up) before it starts transmitting the data.
It turned out that this delay was not enough for my setup, so when I changed this to 1000 us (1 ms), the code worked like a charm even without the receiving functions in between! To do this modification, I opened the RF24.cpp-file (in the arduino Sketchbook libraries folder) with notepad, changed the delay, and saved the file.



Arduino Mini
Just as I managed to get a working Arduino code for the nRF, two Arduino Mini 3.3 V landed in my postbox, awesome timing!


One little problem; the Arduino Mini does not come fitted with an USB to Serial-chip to enable programming over USB.... luckily for me I had an USB to Serial adapter laying around (used for debugging AVR's, as I wrote about in this tutorial-post) that I could use to program the Arduino.

Here's a pic of when I have soldered an nRF to the Arduino and uploading code with the USB to COM adapter via a breadboard (out of sight) so the colored cables does not match the pins...


Off course this didn't work straight away either, I found out that when using this kind of FTDI-adapter you have to press the reset-button on the Arduino Mini just when the Arduino-IDE starts to upload the code to get it working! A better buy would be one of these which comes with an automatic reset-pin ("DTR").

I soldered the nRF to the Arduino, and glued them together with some hot-glue, which was also used to attach the unit to the power meter. Plenty of unoccupied room in the meter behind the LCD, and perfect position for a wireless transmitter!


Here you have the wire diagram: 

I started off by just uploading a simple transmission code on the Arduino mini, that would send a dummy byte once a second to confirm a working setup. I  soldered everything together,  plugged the meter into an outlet and kept my fingers crossed as I watched the Arduino-Serial monitor connected to the receiving unit, and.... noting (of course!)

After several hours of debugging, (I thought I had burnt the nRF by hooking it up directly to the power-meters VCC-pin)  It turned out had I accidentally  uploaded a non-working code to the Arduino Mini.... FAIL!!!

I had cleaned up my working code, and shifted some parts around, it seems like you can't open the writing/reading-pipes on the nRF before you set the datarate/payloadsize/PALevel...

Anyway, the setup I found working is grabbing the power directly from the battery (3.6 V soldered to the underside of the PCB) rather than the VCC-cable (which i think is a bit flaky, and is connected to the RAW-pin on the Arduino, which has a built in 3,3 V regulator. I'm not sure this modification is necessary, but it ensures that the nRF and the Arduino gets 3.3 V. (The pictures above are not connected to RAW, but the Arduino's 3.3 V)

Here's whats transmitted to the computer connected Arduino and printed in the Serial monitor:


I have spent some time looking at ways to store and plot this data in the cloud. One interesting approach is to send the data to a website like http://emoncms.org/ and use there ready to use energy-viewing graphs. With the help of a small python-script I wrote, I can easily send the data from my raspberry pi-server to my account on there website where I have the option of making graphs.

I have also been working in the program called "Processing" which is pretty much the same as Arduino-IDE but for graphing and doing stuff with the data.
I have so far programmed a working graph that shows the data output from up to 6 wireless energy meters, it  also logs the data with timestamp to a csv-file. See the processing-code at the bottom.


Above you see a screenshot of when I have plugged in two energy meters (1 and 2). Nr 1 shows a soldering station which i obviously changed the power on allot during the readings. Nr 2 is a 4-step lamp that i flickered from 3 to 0 to 1 to 2 to 3. as you see i didn't stop at 0 for a very long time, so the graphed mean value stopped at ~10W.

You might wounder why the red and green line (nr 1) sometimes differ? That's because I have the meter to transmit the average=red and the maximum=green power readings on every third power reading. This interval is easily changed by typing 1:1 or 1:4 to change the interval on meter 1 from to 1 or to 4 readings in between transmissions.

I had a hard time figuring out how to transmit this new interval from the computer nrf to the meter, because if I in between every transmission changed the nRF to a receiver, the power consumption would cause the whole meter to stop working.

This time I had to do some serious thinking, and I ended up using the possibility to alter the autoAck-payload. A function that normally sends an "OK" from the receiving nrf back to the transmitting nRF to confirm the transmission. I found out how to alter this value to send something like a "2" instead, or some other integer that would be a new interval. This was exactly what I needed, See the code at the bottom!

Her's the working Arduino code, first for the Energy Meter then for the computer connected receiver-Arduino. At the very bottom you have the processing code:


Here's the code for the receiving Arduino (connected to computer via USB)

And finally the Processing code that can be used to read and write to the computer connected Arduino through its serial connection (over USB)

Monday, October 20, 2014

Power Plug Energy Meter Hack

It has been way to long ago since I tested my capability of hacking things.

Since i am an energy engineer, I have been looking for a cheap and easy way of monitoring my power consumption. 
I know there are other hackers out there that have already worked on this problem, and I have seen dozens of hacks on smart and dumb house-power meters, but only a few that covers power plug energy meters. 

You have the Tweetawatt - awesome, but not my cup of tee (i prefer to write my own software for AVR or Arduino) and still ~55$ each...
And a guy named Connor Wolf has an awesome project where he builds his own and a video where he tares a few standard power plug meters apart

I have seen how cheap the China-version of the energy meter is (£7,86), and when i saw the tare-apart video where he takes one apart, I went ahead and ordered two pieces of the EU-type (230V 3,6kW). Of course my intention was to convert them to my own cheaper version of the Tweetawatt.


My final goal is to connect them to the internet either via an nRF24L01+  and my rPi-setup, or with an ESP8266 Wifi adapter (if it will ever arrive in the mail box...)

The future goal is to use an home made Android app to graph the data, i'm not quite there jet, but this tutorial describes how I hacked the power meter and successfully got the voltage, current and power readings to an arduino using interrupts on the CLK. 

The meters showed up last week, and the first thing i did was to open the cover of one of them. 


The guts looked promising since it is very similar to the one in Connor Wolfs video with the 3,6 V battery and the ribbon cable between the two circuit boards. The differences i can see compared to the 110 V version is the big blue capacitor.

The reason I started this project from the first place was because I had seen the ribbon cable labels in the video, so I was very satisfied when I confirmed that the 230 V version also came with the labeled ribbon cable between the power meter and the main processor which sits under the brown circuit board.

The ribbon is labeled: 
VCC, SGND, FREQ, CLK, SDO and SDI as seen here:


I tapped into all of the 7 wires, (7?) yes there are 7 wires, only 6 labeled. closed the case, and plugged it into the wall.

Before i hooked it up to my awesome £6, 8-channel, 24 MHz logic analyzer and started testing it in the logic analysing software, I firs checked all the cables with a multimeter to see that none of them was connected to mains (this video shows that the Kill-a-Watt meter has 110 V on the ribbon cable strangely enough). But the China version was safe on all 7 wires and the five which weren't VCC or GND  got its own channel on the logic analyzer:

###WARNING!!! I'm not an expert in HVAC and there are lots of knowing people that read this article on Hackaday.com and informed me that hooking up the logical analyser like this is an terrible idea! It seems like the energy meters DC-line is not grounded, but instead use Neutral as ground, which can be very different from your computers USB-ground... DO NOT USE MY SETUP, It can be both dangerous and harmful to the computer!

If you want to test the SPI on a non-grounded device they have a lot of suggestions on how this should be done, optical isolation sounds pretty smart (maybe there are even optically isolated USB-hubs you could use?!) I guess I was lucky not to blow up my computer, or my self...


I must admit that this was the first time I have ever attempted to sniff a data communication before, so I had to do a little research. I recognized the CLK as the clock wire in SPI, and guessed that the SDO and SDI was the same as MISO and MOSI but where was the SS (chip select) wire?

My hope was that maybe SPI can work without chip select when there is only one slave that listens, but that would make it heard to know when a transmission starts and end!? how does it sync?

Well, it turns out that I was right, This is the output on a run with nothing connected but the meter:


(click picture for larger version)

Yey, This confirmed my theory and it showed that the FREQ-pin was giving a 50 Hz signal, not at all involved in the SPI communication (nope it's not the SS-line). and that the un-labeled cable was the same as the VCC-labeled pin (high = 3,6V)

This project has improved my analyzing skills allot, and I had to learn how to set up the analyzer to debug the SPI-signal (great SPI-info)

To read this scatter as SPI you need to define the start (where to read the first bit in a byte from)
1. press T1 or hit 1 on keyboard
2. put marker in between SPI-signals (where it's obviously not in the middle of sending a byte)
3-4. Add an Analyzer, choose SPI



Next step is setting up the SPI-analyzer:
1. Press settings
2. zoom in on the first byte, and try and figure out what settings that is used. (see pic under this as well)

Start by "Re-run starting at marker T1" as in picture bellow.
I found that my data is read when CLK is rising "Trailing Edge" and comes in sets of 8 bits (1 byte). 
Note the last MOSI-byte going low, only catched by the trailing edge of clk=>trailing edge
This is how the bits in a byte are interpreted on trailing edge: 


When the CLK goes high, the status on the MOSI and MISO are converted to either 1 or 0. After 8 bits, you have a byte which can be translated to decimal value, as seen above:
MOSI = 1111 1110 => decimal 254
MISO = 0001 0000 => decimal 16

At this time, there was one happy geek in the house!

Decipher the data

Now I had figured out how to sniff the data communication, I still had no idea of what, and in what format the data was sent.

I figured that my best chance of decoding the data would be to sample lots of data and then compare it. So i started sniffing the setup when connecting my soldering station which was perfect since it has the ability to choose different power settings, and for heavy load i used a 1,8 kW water heater.

When comparing the data, it was quite clear that there is not much going on here.The data is sent in chunks of 70 packages at a time, followed by a 47 ms delay. Each package contains 8 bytes, and luckily for me, the first 68 package seems to be the same every time, independent of the wattage reading and they all look like this:

Byte MOSI MISO
1 255 0
2 255 0
3 255 0
4 254 0
5 30 0
6 254 16
7 254 3
8 254 193

Sometimes (under high loads) the 16 reads 80, but that's probably because the 7th bit is misread (i haven't found a pattern):
16 = 0001 0000
80 = 0101 0000

But then in the 68th package it always sends:
ByteMOSIMISO
12550
22550
32550
42540
5300
6254144
72543
8254193

Same thing here, 144 sometimes becomes 280
144 = 1101 0000
208 = 1001 0000

Which i think prepares the Master that next 8-byte package will contain important stuff.
This is what comes out in package 69 with different loads:

ByteSISO 0WSO 8,5WSO 20WSO 44,5WSO 1860W
19400000
21280000
3000000
4000000
52400000
6254115116115115111
725423810231236191
82542498412321518

Which i figured out to be:
Voltage = 2*(Byte6+Byte7/255) 

Which makes sens because when it goes from Byte6=115 and Byte7>238 to Byte6=116 and Byte7=10 It implies a moderate increas in voltage (231,9V=>232,1V), but under high load, one can expect a voltage drop, and when running at 1,86 kW: Byte6=111 and Byte7=191 (223,5V) seems to be correct!

I guess Byte8 represents a very small fractions of voltage level, so i skip that one.

And the last 8-byte package hopefully gives me some sort of current measurement value so that I can calculate the power!?
Package 70 looks like this with different power loads:

ByteSISO 0WSO8,5WSO 20WSO 44,5WSO 1860W
12200000
2254001168
32542162715645
425416811431163243
52000000
6254000014
72540174090137
825425521324870

Where I have tried hard to find out what bit 2 to 4 means, please help me with that in the comment field!!!! The meter displays power factor, could it be something with that?

Anyway, I was luckey, it turned out that the last three bits sends the power value like this:
P=(Byte6*255+Byte7+Byte8/255)/2

And to get the current:
P=U*I means I=P/U  and I have all i need!!!!!

And I am one very happy engineer!

A bonus is that changing the setting to view voltage or current, doesn't change the SPI-data.


Arduino MISO sniffer

I can't have a PC next to every power plug energy meter i have hacked so next step was to program a micro controller to do the SPI-sniffing for me.

I have been using AVR's for quite some time now, but this is my first Arduino project, and for testing purposes I'll be using an Arduino Nano, but I have decided to use an 3,3 V Arduino Mini when it's time to solder everything togeather since I have a 3,3 V battery in the meter, and I am planing on transmitting the read data with either an nRF24L01+ to my rPi-setup, or the ESP8266 Wifi adapter (if it will ever arrive...). I wonder if I need a big fat cap to supply the current when sending data like the Tweetawatt!?

Anyways, my plan is to send the data to Gdrive so that i can reach it from an android app or something, but that's future work! If you read this, and now how to log data from ESP8226 to G-drive or Dropbox, I'd appreciate if you gave me some tips!

I first thought of using the built in SPI-function, but learning how to use the "bitbanging" technic on SPI sounded allot more fun! (and I'm not sure the built in SPI would work anyway without SS)

This is the psudo chode I wrote:
1. Connect GND, CLK (green cable) and SO (blue-white) to Arduino (CLKto INT0 and SO to D5) (Arduino 5V from USB for now)
2. Setup interrupt (ISR) on INT0-pin (D2) and make it trigger on rising edge (se ISR-info)
3. When trigger occures: loop as long as CLK is high while logging the time
4. When CLK goes low: check if the delay was between 1-2ms, if so then we are in clk-sync and next clk-rise will be the start of a new byte (this is the delay in between every one of the 70 packages in a transmission)
5. Let CLK-interrupt trigger 40 times to skip the first 5 bytes of the current package
6. Save status on pin 5 (MISO) every time CLK-interrupt triggers to two integers (the next 8*2 times, which will be Byte6 and 7) by using shifting bits method "<<"
7. Let clk trigger 8 more times to finish a complete package and stay in sync
8. check if Byte7!=3, If true: its the 69th package => use byte 6 and 7 to calculate U and proceed with the next step, otherwise (Byte7==3) then: set sync=false and go back to step 3 and wait/look for next package.
9. Let CLK-interrupt trigger 40 more times to skip the first 5 bytes of the 70th package
10. Save byte 6, 7 and 8 in integers by shifting bits each time a new bit is read (8*3 times).
11. Calculate P and then I=P/U
12. Send U,I,P to computer for debug.


And believe it or not, after a good couple of hours of debugging it now works like a charm!


Here is the code that now sends the data to the Arduino-IDE, but is easily changed to an nRF24L01+ and hopefully the ESP8266  as well...



Update!

I now have a working setup where the energy meter is completely wireless with an Arduino mini pro 3,3V and a nRF24L01+ module! =)
Se next post for further information.
/Kalle

Monday, August 25, 2014

Move program between terminals

Finally I have found an easy way of moving a running program from one terminal to another in Linux.

1. Install a neat program called "reptyr"
     $sudo apt-get install reptyr
2. start a never ending program in one terminal
3. start a second terminal and find the PID of the never ending program by running
     $ps -er | grep nRF  
          -where the "nRF" part is part of the never ending program name
          -you might want to make the terminal window broader to see all the text
4. look after the PID that corresponds to the ps-output:
     pi         2801     2800     1   20:57  pts/1       00:00:01 python3   /home/pi/nRF24L01p.py
          -the PID is the number 2801 in the example above.
5. in the second terminal, run:
     $reptyr 2801
and the second terminal will print out 11 rows of text starting with [+] to tell you everything worked, and at the bottom show the out and input of the program.
The first terminal will go on and ask for a new input and act as if nothing has happened.


Another useful thing with the PID is when you want to kill a process. just type $kill 2801 where 2801 is the PID

Monday, December 2, 2013

AndroidPlot in AndroidApp

This will be a simple step by step tutorial in how i managed to get the AndroidPlot up and running in one of my android apps.

The creators of the function has a great tutorial on there website (allot of code is straight from there tutorial), but as always they assumed i had more knowledge than i do to get it working straight away... Since it wasn't enough to follow there steps, and i had to spend allot of time searching the internet for answers i figured i would post a step by step tutorial on how i managed to get it up and running.

1. Download the latest version of the "Core Library" .jar-file from there download page. (the only file you need to download)

2. Save the file into your "libs" folder, and it will automatically import the library under "Android Private Libraries" (if not, left click your project foldet/Properties/Java Build Path/ tab "Libraries" / "Add JARs"...)

3.Create folder res/"xml" which android recognizes as default xml-resources folder.

4. Create two xml-files, first one named "line_point_formatter_1.xml", and secound one whit "2" instead of "1"....

5. paste following code in the first xml-file: (you can put a linebreak in between every setting to get a better overview, but my code-viewer wouldn't let me...)
<?xml version="1.0" encoding="utf-8"?>

And this in the secound file:
<?xml version="1.0" encoding="utf-8"?>

6. Create a new xml file that you name "dimens.xml" and put in the res/values folder. Paste this in the file:
<?xml version="1.0" encoding="utf-8"?>


    
    16dp
    16dp
    10dp
    20dp
    13dp
    13dp
    15dp
    15dp
    20dp

7. Create a layout file in res/layout and name it something like "plotlayout.xml". Paste this code in the file:







8. Create a new .java-file in the src/"com.example.NAMEOFYOURPROJECT" (where most of the java-files are stored) and name the file "Plots.java"

9. Paste this in the file:
package com.androidplot.THENAMEOFYOURAPPLICATION;   //all in small case letters. 

import android.app.Activity;
import android.os.Bundle;
import com.androidplot.xy.*;
import java.util.Arrays;
 
/**
 * A straightforward example of using AndroidPlot to plot some data.
 */
public class Plots extends Activity
{
 
    private XYPlot plot;
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.plotlayout); //The name of your plotlayout.xml-file!
 
        // initialize our XYPlot reference:
        plot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
 
        // Create a couple arrays of y-values to plot:
        Number[] series1Numbers = {1, 8, 5, 2, 7, 4};
        Number[] series2Numbers = {4, 6, 3, 8, 2, 10};
 
        // Turn the above arrays into XYSeries':
        XYSeries series1 = new SimpleXYSeries(
                Arrays.asList(series1Numbers),          // SimpleXYSeries takes a List so turn our array into a List
                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
                "Series1");                             // Set the display title of the series
 
        // same as above for series 2
        XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
 
        // Create a formatter to use for drawing a series using LineAndPointRenderer
        // and configure it from res/xml/config-files:
        LineAndPointFormatter series1Format = new LineAndPointFormatter();
        series1Format.setPointLabelFormatter(new PointLabelFormatter());
        series1Format.configure(getApplicationContext(),
                R.xml.line_point_formatter_1.xml);   //Name of the 1'st xml-config file
 
        // add a new series' to the xyplot:
        plot.addSeries(series1, series1Format);
 
        // same as above:
        LineAndPointFormatter series2Format = new LineAndPointFormatter();
        series2Format.setPointLabelFormatter(new PointLabelFormatter());
        series2Format.configure(getApplicationContext(),
                R.xml.line_point_formatter_2.xml);   //Name of the 2'nd xml-config file
        plot.addSeries(series2, series2Format);
 
        // reduce the number of range labels
        plot.setTicksPerRangeLabel(3);
        plot.getGraphWidget().setDomainLabelOrientation(-45);
 
    }
}

10. Add these lines to the "Manifest file" (found in the root, and named "YOURAPPNAMEManifest.xml")

And put the lines in between these tags:
 and 

11. Now it's time to test the plot. create a button with an onClickListener whit this code in it:
Intent i = new Intent(getApplicationContext(), Plots.class);
startActivityForResult(i, 2);
which will start a new intent which call the Plots-class which in term opens the plotts-layout showing the graph of the numbers.
Now when you know how the file-system works, try next tutorial they have posted, which is a dynamically updated plot over the phones tilt... =)

Saturday, November 23, 2013

Autostart Raspberry pi VNC and server

Hi!
Last week i finally configured my Rpi, and had it setup as a server to get 24/7 access to all the gadgets in my apartment. I'm not very familiar with linux, and therefore it is probably a good ide to write down how i managed to do so, for future setups =)

First of all i wanted to get access to the Rpi from my main computer. I had two options, either just by a terminal (SSH), which is probably best for speed, or configure a remote desktop (VNC) to mirror the pi on my main computers screen. Since i'm not to familiar with the linux terminal, i figured i'd start off with the VNC like this...

Setting up remote desktop (VNC) on the Rpi using the program TightVNC according to this guide (skipped the SSH-part in the beginning):

Install the TightVNCServer on the Rpi like this:



Then try and start the server by entering: (change the resolution to the screen res where you are going to view the desktop)
The "1" is an ID, (you can start several different servers)
The program will now prompt for you to enter a password to get access to the remote desktop, set one!

There might be an permission issue, so to make sure that wont happen, do this:  (where "pi" is the username)

The VNC-server nr "1" can later be closed by typing:

Install TightVNC on Windows machine

Now that you have your VNC-server up and running, it is time to install the TightVNC-program on you main computer from there website:
2013-03-16_162457
When done, startup the TightVNC-Viewer (not the server), type in the IP-address and the ID that you specified on the pi and press "Connect". A good ide is to configure your router so that the ip of the Rpi never changes...

If the server is running, a prompt for the password will show up, enter it and a window with the Rpi-desktop will popup =)

If you make it full-screen, the way of getting out is by pressing alt+ctrl+shift+F.

Autostart VNC-server when Rpi boots

Next step is to get the server to start automatically when the Rpi starts up. There is no point of having a remote desktop if I every time the rpi starts have to have a keyboard, mouse and a screen attached to it to startup the server...

Create a file named tightvnc in the init.d folder, and open it in nano to edit its content:


Enter the following:
Press ctrl+x and y to exit and save.

Now we need to set permissions to the file to make it executable:

And the last thing we’re going to make is to update the rc.d file (which tracks which initilization scripts are in the /init.d/ folder):

Now it is time to test it: Reboot the Rpi:


And try connecting the ThightVNC-program on the main computer.

Autorun other scripts when Rpi boots

To autorun a script that doesn't need permissions when Rpi starts is a little easier. Take my nRF-server for instance:
Create (if not allready created) the folder


Then add a file with the ending ".desktop"  and edit it in nano:


Edit the file like this:
Where the importent stuff is the terminal=false (we want to start lxterminal), and the "Exec" that executes the script "sh /home/pi/a.sh" in the lxterminal, which is the script that starts the server...
Exit nano with ctrl+x and save (press y)

Now to make the .desktopfile executable:


Reboot the Rpi, and you can see that the lxterminal has started the NRF-server in an open terminal!

Monday, May 27, 2013

Raspberry pi: nRF24L01 and TCP

This time I will describe how I got a Raspberry pi (Wheezy) to work as a Python server that controls a RF-transmitter (nRF24L01). The server takes commands either from a TCP connection (internet) or via the keyboard, and broadcasts the data through the RF-transmitter to the receivers i have set up in my home automation system. See my other posts covering how to use the nRF with an AVR, and the construction of a  multi-functional remote control.

        

Why use a Raspberry pi when i already have a working TCP-server on my PC?

Easy answered:
  • I do not like to have my PC up and running 24-7 due to the facts that it's noisy (stationed in my bedroom)
  • The RPi takes much less energy (runs on a 1000mA cellphone charger)
  • I don't need any other parts other than a RPi, a nRF24L01(+) and cables, since the RPi has a 3,3V power supply!

Setting up SPI on RPi

First of all, you must have a working copy of raspbian, I use Wheezy (made a small tutorial in how to set it up). The RPi has a built in hardware SPI, which we first has to get up and running according to this guide, and here is how i did it:

Start a terminal like the LXTerminal and follow these commands:



To check if the SPI is working (optional) you can connect the mosi-pin to the miso-pin (GPIO10 and 9, see picture), and run the commands in a terminal:




Quick2Wire

Quick2Wire is a tool that makes it possible to control the GPIO and the SPI via python. We need to install quick2wire, download the quick2wire python plugin (API) and gain root access to the spi.
Start by downloading the plugin from there website. Extract the zip-file by right clicking and unzip. Now open a terminal window and change directory so that you are in the extracted folder called "quick2wire-gpio-admin-master" then enter the following commands:


Now log out from the RPi and back in again. The power button at the bottom right quorner has the option to log out. Log back in by typing your username "pi"/enter, then your code "raspberry"/enter...

To gain root access for the SPI so that you dont have to use the "sudo" command in front of every bit of code, I followed this guide, which tells you to do this:


Finnish by remove and reattach the power cable to restart.

Python 3

Now it's time to install python3 which is needed to run the code. Open a terminal and run these commands:


Now to use quick2wire with python, you need the python API which can be downloaded from this site. Download it, and unpack it to a location on you SD-card (no installation required!)

Setting up the hardware

The setup is very straight forward. Connect the wires like this (see red circles in the picture):
RPi GPIO9     (Pin 21)    to RF  ( MISO )
RPi GPIO10   (Pin 19)    to RF  ( MOSI )
RPi GPIO11   (Pin 23)    to RF  ( SCK )
RPi GPIO8     (Pin 24)    to RF  ( CSN )
RPi GPIO18   (Pin 12)    to RF  ( CE )
RPI 3.3V        (Pin 17)    to RF  ( VCC/3.3V )
RPi Gnd         (Pin 25)    to RF  (GND)
(IRQ-pin on nRF is not used in this example)

nRF24L02+ (top view)


nRF24L01 (only one of each VCC and GND-pin has to be connected!)


I think the CE-pin should work on a different pin (it would be convenient to put it on GPIO25) since it doesn't have anything to do with the SPI, but I haven't tried that yet...

The python programs

I got the basic nrf python code from this program (plus a lot of help with the steps above) from Jussi Kinnunen, all creds to him!
Download  my version of the program, as well as my TCP-server program. which is well commented to make it easy to understand. You see the codes below:

nRF24L01p.py


TCP_Server.py



To run the program, create a third file, and name it to something like "a.sh", the ending "sh" means shell file, which is runnable. Fill the file with these commands:
(change the path "/home/pi/" to where you have the quick2wire-folder!)

This will make sure the path is imported every time the script is run! If anyone knows how to permanently add the path, please tell me in the comment field!

To run the program, all you have to do now is to set the working path in the terminal to where you store the a.sh-file with the cd-command and type


This is a screenshot from the code running in the terminal:































As you can see, the program starts by asking if you want to run it as "rx" (Receiver) or "tx" (transmitter). I chose transmitter by typing "tx"/enter.
Then it prints out all the registers that the code changes (or sets) and then starts a server loop in a background thread (TCP).
When this is done the program waits for either the user to type in data to send (3 bytes in my example), or for a command from the TCP-server.
In the picture above, you can see that i started by typing "123" on the keyboard, which was sent to the nRF and broadcasted to any nRF-receiver with address 0x12. As you can see the STATUS register after the broadcast tells me that the transmission failed (0x1E), since i don't have a receiver running at the moment... a working transmission would give the result "0x2E" (when the EN_AA is turned on)!

The second thing I did was to send the command "300" to the TCP-server from my home-made android application (can be sent form any TCP-client with the right port number). The TCP-server then calls the nRF24L01p.py and transmits the data like it was inputted with the keyboard.

If a (large) error shows up when you try to run the code, which tells you something about "cannot export the pin number 18 because it is already exported", run the following command in the terminal:



If an error shoes up that tells you that the address is occupied, the TCP-server has not closed yet, and you have to sit down and wait for up to 1min before you try again (I know you can change this timing, but haven't come so far)


If you have any questions or just want to tell me what you think of the blog, just give me a comment in the comment field underneath...
/Kalle