Thursday, December 20, 2012

Suunto ambit on Linux - log file

As requested in the comments of a previous post, here's a link to a comms log between the suunto and a PC. This is only part 1 of 6 of a session where waypoints are uploaded from the watch, followed by the upload of a move.

Hopefully this is useful for someone.

Thursday, December 13, 2012

suunto ambit on linux - part 4

Thought I posted a screenshot of the first reply I could get from the ambit:

The ambit replies with the firmware version "bluebird". Converting the hex to char on the ambit's reply gives:

?>]6 � Ù� �    ���0���Bluebird��������00000000�������� � �E J ãO

 Next step try to understand the protocol...

Wednesday, December 12, 2012

how to reload optware usb stick on asus oplay

Sometime ago one of my dogs decided to eat my asus o'play remote control. Without the remote the unit is pretty much useless. At the same time, I was looking for a way to have a always on machine serving 2 HD on my home network and for that I was using my linux machine but it was bugging me that I had so much power for so little needs.

So I thought that maybe I could turn the asus media player into a samba server. I'd heard that the asus was a linux machine and it's true. Not only that but root access is as easy as telnet to the machine and login with username root and no password.

So I went through the processes described here to install moservices on the machine and this way install samba. It works well and my machines on the network can all see and access the two harddisks.

The other requirement I had was to have one of the HD as the main and the other as the backup. Put everything onto HD1 and then, every day at night to a backup with rsync. Thing is rsync is not installed on the asus o'play and it does not come with moservices, so the next option was to install optware (package management for embebbed linux). Trouble is the asus o'play doesn't have enough space to install it. So I followed these instructions to get it running again. For aht's coming to work, do not follow the steps of cleaning up the USB tmp files. It worked well but there's a few things to note:

1. There's a program that loads the USD HD on the o'play. That program comes with the o'play and you either delete and replace it by your own or you are a slave of how the o'play decides to call your USB HD. For me this is not a big problem because it is enough for me to plug them in at the correct sequence for them to be available in the right sequence on samba. I.e. it doesn't matter how they get mounted on the o'play because the first disk is always going to be called disk1 on the samba share and the second is going to be called disk2 on the sahre, no matter is they are automatically mounted as /mnt/usbmounts/sdb1 or /mnt/usbmounts/sdc1 or whatever.

2. I do have a problem with reloading my optware USB stick though, because that one I need to be loaded to the same mount point other wise it will not work. So, instead of making it a persistent mount point, I'm lazy and follow this steps after each reboot (that only really happens every 3 months anyway):

a) plug the USB stick in and find out where it mounted with df:

BusyBox v1.1.3 (2010.09.07-08:50+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

~ # df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/root                76288     75212      1076  99% /
/dev/mtdblock/2          61440      8608     52832  14% /usr/local/etc
/dev/rd/0                   40        40         0 100% /mnt/rd
/dev/scsi/host5/bus0/target0/lun0/part1 976521568 924004192  52517376  95% /tmp/usbmounts/sdb1
/dev/scsi/host6/bus0/target0/lun0/part1 975592816 921977600  53615216  95% /tmp/usbmounts/sdf1
/dev/scsi/host8/bus0/target0/lun0/part1   7861696    180928   7281412   2% /tmp/usbmounts/sdg1

You  can see my two harddisks and the USB stick above. The HD are the image of each other so they are both used up by 95%. The optware USB stick is the last one (around 8GB with 1.8GB used up).

b) mount / as rw and a few more:

~ # mount / -o rw, remount
~ # mkdir /opt
~ # ln - s /tmp/usbmounts/sdg1 /opt

c) cd to /opt/tmp and run

/opt/tmp/ipkg-cl install uclibc-opt_0.9.28-13_mipsel.ipk
/opt/tmp/ipkg-cl install ipkg-opt_0.99.163-10_mipsel.ipk
d) Update optware to the latest version

/opt/bin/ipkg update

e) Find rsync (you may have to install it with optware)

ls -la /opt/bin

f) To make rsync backup your files from the main HD to the backup HD issue the command I spoke about on a previous post

rsync -avh --delete /path/to/main/drive /path/to/backup/drive

suunto ambit on linux part 3

Investigation is my favourite part of any project and especially the part where I start making things happen.

So on part 2 I got to check the protocol between the computer and the ambit. It's not not 100% clear how it operates. Just for fun, I decided to change the HDI program to send some of the packages that I can see my windows machine is sending to the ambit.

See below the screenshot of me sending a command I took from the windows sniffer. I don't get a response from the ambit BUT it reacts to that command because the lock icon disappears and the battery icon also disappears and turns into the little circles that indicate what ambit screen you are on. After briefly changing to the above, it goes back to the lock and battery icon.


Just for records, here's the full HDI package including my modified write to the ambit program on the hidtest folder. There's a lot of files you will not need in this package if you are running linux but I thought I'd leave exactly as I currently have it (see my first post on this series for other packages you require to be able to run this).

Suunto Ambit on Linux part 2

ok, on the windows side of things, I'm also learning quite a lot. I downloaded the usblyzer program. It's a 30 day free trial tool that does wonders. I also downloaded the free snoopy pro. It does the same thing and it's free, but the usblyzer interface is better. If I take more than 30 days with this project,I will switch to snoopy pro.

Here's a screen shot at some of the info I can get for the communication between the suunto ambit and my computer:

See the selected item. It's a packet sent to the computer (in). I still can't understand the data exhange but there are some packets that correspond to my set waypoints because they are in plain text. I'm assuming there's a request for data of a certain type, say for example waypoints and ambit replies with all the waypoints following some protocol I now need to determine.

The goal is to send a request and receive something back. I will try to send a request for battery level and see what comes back. But what (if any) is the command for battery level. I suppose that once the data exchange is complete and the watch is only connected to the computer the only major thing going on is the battery level information coming from the watch to the computer, perhaps after a request from the computer...

Another thing to note is accomplished by leaving the sniffer on while you disconnect and reconnect the watch. From this you can see the exchange of data where the manufacturer name (Suunto) is transmitted and the model number as well as the serial number. You can also see that the watch will declare what seems to be the current firmware name "Bluebird". See below:

 The last interesting thing to note is a transaction of a route I created on a recent visit to Dubai. There's an entry from the ambit back to the computer with each of the way points on the route. See below:

If only I can find out more of the structure, we will have a little more...
Note also the record ID for the device which is decimal 63 or hex 3F. This is needed because all transactions need to start with this value.

Suunto Ambit on linux

I am a suunto user. I am a linux user. I would love both to work together and there's nothing on the internet. That means I have to make my suunto ambit talk to my ubuntu.

;-) So today I spent some time looking and sniffing data on windows to try to see what was going on and eventually take some of what I learn over to linux. So I found the following:

1. suunto vendor ID: 0x1493 Product ID: 0x0010

2. After hours looking for some kind of USB to serial bridge driver, around the CP201x driver, I think that this is probably not the way to go and the suunto uses a generix HID driver. At least it seems to be recognized as such by windows and it definitely gets recognized as such on linux.

The reason why I went on looking for a CP201x driver was because I found a folder on the suunto installation files on windows that references that chip. I gave it up for now, but this may still be the way.

3. On linux, I downloaded the HID API for Linux, Mac OS X, and Windows and managed to compile and run the test program (you need the following two packages to start):

sudo apt-get install libusb-1.0-0-dev
sudo apt-get install libudev-dev

So far I go the following info on linux (note that the watch gets recognized automatically as a general HID device - type dmesg to verify after plugging in the watch to your linux machine). I edited the hditest that comes with the hdi library to point to the proper vendor ID (i.e. 0x1493) and product ID (i.e. 0x10).

So I can detect and I can open the device. I can't read or write to it yet, but I'm off to my windows computer to analyze the communication protocol. Wish me luck!

Monday, October 22, 2012

sensorNET, change of plans

Judging by the popularity of this blog, we seem to have quite a large number of people interested in this last sensorNET project. We have however decided to adjust its goals a little bit. It all has to do with a parallel project that is under development as we speak: cloudruge, a cloud based CMMS, for Computerized Maintenance Management System. This is not the place to discuss the project, so please visit the link above if you would like to know more.

But on this blog we are interested in making things and we are going to take everything we knew from the sensorNET project and have the sensors report back to an online CMMS (these systems basically automation the maintenance management process of a company). This will allow work orders to be automatically issued on condition.

For example, if you place these sensors on rooms that need their temperature controlled, you can set them to report to the maintenance system that the temperature is too high by issuing an automatic Work Order, or a direct call for service. This is similar to temperature sensors on server rooms that report problems to network administrators. It is however more powerful, because the CMMS allows for advanced reporting and linkage to warehouse spares for example, keeping it all integrated.

The tests will start with the initial CMMS program that originated cloudruge, an open source program called maintenancedB which you can check out in here and the basic goal of setp 1 of this project is, like with the sensorNET project, the reporting of sensors directly to the CMMS and the automatic generation of work orders.

More news coming soon.

Sunday, January 29, 2012

sensorNET - code

As promised on my last post, here's the code as it stands today new items tagged as [NEW]:

1. Ability to choose DHCP or static.
2. If static, ability to set IP, subnet and gateway addresses.
3. Saves settings to EEPROM so they are available even after power down.
4. DHCP selected out of the box
5. EEPROM space for MAC address and device serial number
6. Configuration done by Serial connection at 115200baud
7. Rock solid with 12V power supply (will reset randomly with USB power only).
8. [NEW]: console automatically scans up to 32 client addresses and gets board id number (to be used to collect list of commands for the board from the server) for the ones it finds.
9. [NEW]: device scanning is shown through a serial connection for debugging purposes
10. [NEW]: started developing client board code (already receives scanning command from master and replies with code id number).
11. [NEW]: Client HW includes dipswithes to set client address.
12. [NEW]: Main console HW includes 20nF capacitor between RESET and GND to allow for proper reset of the wiznet Ethernet chip (I was having trouble with this), so I think the capacitor is a requirement.

I am currently at the point where I need to start testing the physical devices with the server software. I already have some read and write APIs and a some degree of interaction with the server (create users, create feeds, etc) that I will start using until the final server code is developed by my colleagues. I will have to develop a simple client database (see my previous post on this). Probably at the end of next week I will be able to start posting some of teh server side software along with the device software.

code is posted after the break (note two segments, one for the console, another for the client) BEFORE USING run this through a text editor like notepad and replace "lessthen" by "<" - I had to do it to allow it to be posted on the blog and not be used as a HTML tag:

sensorNET - Project Update

I have been working on the sensorNET project and I thought it was time for an update on where I am at the moment. As I go about developing the code, new questions arise and sometimes, those questions push the project into some new direction I never considered before.

Consider the following shematic:
The connections from the console to the client boards is nothing new (we distribute both power and data connections to the clients). There's also nothing new in that the main console connects to a main server that organizes and saves data sent from the console and makes that data available through user interaction with read and write APIs (the thingspeak and pachube model).

New proposed server extra-functionality
If we consider the above, however a few questions arise, specially if we want to make this project truly universal, to the point where anybody can contribute with new client boards. Those new client boards need to have a set of commands that the main console cannot know beforehand and must be declared to the main console afterwards without reloading firmware.

Since we are connected to the internet (or to a LAN server) anyway, we may store the parameters of each new board on that server and then send the configuration to the main console once it detects that type of client connected to it. If we follow a clear standard it is possible for he main console to handle future boards.

Conceptually, the main server will require a table to store new device data (table_device: id, developer_name, board name, description) and another to store the list of commands the new client may receive from the master console (table_device_command: id, device_id, command_value, command_description).

Developers of new client boards need only to register their boards and specify their commands. Needless to say this allows for complex boards, capable of simultaneous input and output. For example, we can have a board that has a temperature sensor and a relay output. Sending a 0x01 to the i2C address that board is connected to will make the board send the temperature value back, if we send a 0x02, we activate the relay. Sending 0x03 deactivates the relay.

The concept of rules
After the user configures the network parameters and the server address on the main console using a serial connection (possibly dedicated configuration software will have to be developed, more on this on another post), we are left with a board connected to I/O and in turn connected to the internet. The input data may be local or remote and we may act on the world depending on the data received. For example if we consider a system that contains two relays (R1 and R2), one controllable LED, a local temperature sensor (that may live on the same board as the relays or on another connected to the same console) but also reads a temperature feed from another public feed from another user available on the server. In summary we have:

a) one local input (temperature)
b) one remote input (temperature from another feed)
c) one output R1
d) one output R2
e) one output controllable LED L1

and we would like to achieve the following:

1. post our temperature data to a public feed on the network server
2. activate relay 1 if local temperature above 25
3. activate relay 2 if remote temperature above 25
4. deactivate relay 1 if local temperature below 22
5. deactivate relay 2 if remote temperature below 22
6. activate LED if both local and remote temperature above 25
7. achieve this without uploading new firmware on the main console

To do this we could make use of the concept of rules, which is a list of actions specified on the server that would look a bit like a list of firewall rules. These are then uploaded to the main console that saves them on EEPROM and then starts playing the new rules after a reset (I can't get rid of the need to do a board reset).

Because we are connected to a server some of the actions to be taken (Outputs) may be on server side, for example send an email or an sms through a sms service.

I'm quite confident I can achieve what I describe above. See my next post for the status of the programming on the project and for the code as it is at the moment.

Friday, January 20, 2012

sensorNET - console code status on the 20th January 2012

I completed the network setup console code. The code posted below includes:

1. Ability to choose DHCP or static.
2. If static, ability to set IP, subnet and gateway addresses.
3. Saves settings to EEPROM so they are available even after power down.
4. DHCP selected out of the box
5. EEPROM space for MAC address and device serial number
6. Configuration done by Serial connection at 115200baud
7. Rock solid with 12V power supply (will reset randomly with USB power only).

Things that I would like to solve with this version:

1. Ability to auto reset to activate changes (currently the user needs to use the reset button).

Next steps:

0. Organize the code in several files, instead of one large one (main, i2c, serial_comms, webclient, webserver).
1. Box the prototype boards (both main console and sensor board prototype)
2. Add screw terminal connections
3. Code i2C implementation in the main console and, at the same time,
5. code i2C code implementation on the client sensor board

code after the break (compiles with Arduino IDE version 1):

Monday, January 16, 2012

sensorNET - Maximum sensor cable distance

While developing the boards for the sensorNET project, I thought about using i2C as the bus the client sensors connect to. This is because atMEGA328P supports it well and the wire library for the arduino is stable and mature. The problem I thought I could have was related to the maximum cable length specified for the i2C protocol which is, after all, used as inter-chip communicator, i.e. between chips that are located quite close, often within the same PCB.

The maximum cable capacitance for use with i2C seems to be between 400 to 500 pF (see this and this). I think at this point it is reasonable to assume I will be using 4 core cables (2 supply + 2 data, SCL and SDA) and probably we will go to something similar to CAT-5 cable (2 + 2+ 2 extra), depending on cost.

The capacitance of cat-5 cable is 50 to 70pF per meter at 100KHz (see here, page 10). Considering the worst case scenario (400/ 70 =) 5.7m is therefore the maximum cable length between the sensors and the main console. This seems very reasonable to me.

Friday, January 13, 2012

sensorNET - utility to initialize arduino EEPROM

On the sensorNEt project I'm saving data to EEPROM and, during development, I have the need to test programming with the EEPROM as it comes from factory, i.e. with all bytes set to 0xFF. because I write and clear the memory meny times, I needed a fast program to re-initialize the EEPROM to 0xFF. Yes it's simple but it's always a good sketch to keep on the utilities folder (besides, it displays a nice progress line on the serial monitor!!.

Here it goes:

/*this sketch initializes EEPROM with 255 for all addresses*/
/*for atMEGA 328P */
#include <EEPROM.h>
void setup(){
  int counter = 0;
  //write a new "." every counter_step
  int counter_step = 32;
  int current_step = 32;
  for (int i = 0; i < 1024; i++){
    EEPROM.write(i, 0xFF);
    if (counter == current_step){
      current_step = current_step + counter_step;
  Serial.println("Complete! EEPROM reinitialized!");
void loop(){
//nothing to do here! 

sensorNET - configure network parameters on the main console

After some thought I decided the following regarding the code for the main sensorNET console:

1. Main console system, comes out of the box with DHCP support (I have this currently running rock-solid). This will work for 90% of the users.
2. If the user requires static IP addresses he/ she can do so by plugin in an USB cable and configure the console that way. I still have to decide if I will make a program to interface with the console (although only for windows as that's the only platform I can really program stuff for) or through some kind of serial interface.

Here's the header of the latest .ino file:

This version features:
1. DHCP client coded in (implemented).
2. Possibility of changing network configuration through serial connection (development).
Serial comms protocol:
a) console receives a 1 (SEND OUT COMMAND network info command):
serial send out current network configuration as:
info. This is fetched from EEPROM if static or SRAM if DHCP.
b) console receives a 2 (STANDBY for option DHCP or STATIC)
if receive "DHCP" run DHCP code
if receive "STATIC":
request IP address, format XXX.XXX.XXX.XXX (must be valid),
request and standby for subnet, format XXX.XXX.XXX.XXX (must be valid)
request and standby for gateway, format XXX.XXX.XXX.XXX (can be empty)
Save data to EEPROM
Perform hard reset to activate changes
**proceed only when above code is rock solid**
4. user logs in to assigned/ chosen IP address with a browser and gets
diags + sensor list on browser window.

First version of the .ino file to be published within a week with at least the above implemented.

Sunday, January 8, 2012

Force internet connections through one specific network adapter with windows 7

For the sensorNET project, I'm using a development PC (simply my personal laptop) to develop the code for the two main components of the system, namely the main console and the client sensor boards. To do that I need to be connected to the main console on a LAN as this is the use normal users will give the system.

To that end, I connected a cable from my computer to a router. At the same time I need to keep using the internet which, in my case, is accessible through my wireless adapter. The problem is that as soon as I connect the wired network, I loose internet connectivity. As soon as I unplug the cable, the wireless internet connection resumes.

What I think is happening is that the computer routes the traffic that is meant to the internet through the wired connection whenever the connection is available. Apparently windows chooses the adapter with the wider bandwidth to route internet traffic through. How can I prevent this from happening? How can I force internet traffic through one specific adapter?

Depending on your requirements, one of the easiest ways is to go to Network Connections -> right click the wired connection icon -> choose properties -> select "Internet Protocol Version 4 (TCP/ IPv4)" -> click the "Properties" button.

Now on the window that appears, force the computer to use a specific IP address and subnet mask (in my case respectively and but leave the default gateway empty. If you fill in the default gateway IP with the IP of your LAN router, the wireless internet connection will still not work.

This will work. But what if I want the wired connection to use a DHCP assigned IP address? The problem is that on the "Internet Protocol Version 4 (TCP/ IPv4)" properties window, if you choose the option to Obtain an IP address automatically, the setup will not work again!

So we need another solution to the problem in case DHCP assigned IP addresses are required.

The first thing is to keep both interfaces on automatically assigned IP addresses, because this is our requirement, next issue the following command on the command prompt:

c:\ netstat -rn | more

Note the table at the top called "Interface list" and see all your NICs on the list. Just to confirm you are in the right place, see the first number on the left that is a 1 and confirm that corresponds to "Software Loopback Interface 1".

You will also note that the number on the left for your wireless adapter is higher than the one for your wired NIC. This is what makes the computer choose one or the other when both are available - the one with the lowest number is used first. We need to change the priority of the cards (or, in this case, we need to change the metric of the wireless card so that it is lower than the wired card).

Go to "Local Area Connection Properties", the properties window we used before but this time open the one for the wireless card - we want to change it's metric to make it lower than the wired card.  Select "Internet Protocol Version 4 (TCP/ IPv4)" -> click the "Properties" button -> click "Advanced..." and uncheck "Automatic metric". Insert any number lower than the number of your wired NIC but that does not yet exist on the list.

Save your changes and verify that the internet packages are now routed through the wireless connection and forever will be unless you go back on these changes.