Saturday, May 7, 2011

Arduino Uno: Upload new firmware to the Atmega8U2

In the previous article it is described how to put Arduino Uno into DFU mode. To upload a new firmware the dfu-programmer is needed (Ubuntu users: sudo apt-get install dfu-programmer). Windows user can try FLIP software from Atmel. You can upload already compiled hex code from Arduino package or build it from sources (/usr/share/arduino/hardware/arduino/firmwares/arduino-usbserial/Arduino-usbserial-uno.hex or the latest one from github https://github.com/arduino/Arduino/raw/master/hardware/arduino/firmwares/arduino-usbserial/Arduino-usbserial-uno.hex). The steps are:
Put Uno into DFU mode,
sudo dfu-programmer at90usb82 erase
sudo dfu-programmer at90usb82 flash .../Arduino-usbserial-uno.hex
sudo dfu-programmer at90usb82 reset 
reconnect the USB cable.

The LUFA library is needed for building hex file from sources. Download the lib version 100807. Current sources doesn't compile with the latest LUFA(version 101122).
mkdir uno
cd uno
cp -r /usr/share/arduino/hardware/arduino/firmwares/arduino-usbserial ./
wget http://www.fourwalledcubicle.com/files/LUFA/LUFA-100807.zip
unzip LUFA-100807.zip
mv LUFA\ 100807/ LUFA
Fix the LUFA path in "arduino-usbserial/makefile":
     # Path to the LUFA library
     LUFA_PATH = ../..
change to
     # Path to the LUFA library
     LUFA_PATH = ../LUFA
make all
After the successful build the file "Arduino-usbserial.hex" is created. Now you can upload this hex file using above steps.

P.S. After the new firmware upload try to upload and run something using Arduino IDE(the Blink example), to make sure the "USB to Serial converter" firmware works fine.

That's all.

Tuesday, April 26, 2011

Arduino Uno

Arduino Uno is the latest version of the Arduino boards (next to the Duemilanove). The major difference from the previous board is in that it uses the Atmega8U2 micro-controller (instead of FTDI) for communicating with a computer. The Atmega8U2 is programmed as a USB to serial converter by default, but it can be programmed as any other USB devices (keyboard, mouse, joystick and etc...).
Arduino Uno
To upload a new firmware to the Atmega8U2, we need to reset the chip and put it into a DFU mode. There is a description in the Ardunio site how to do that. It can be done easily using 2 M/M jumper wires
M/M jumper wire
Instead of using ground pads(from the description in Arduino site), we can use Arduino's GND pins.
1)Connect Arduino Uno to the computer
2)Hold first wire as pictured in the below image.
3)Connect second wire.
4)Remove second wire then remove first.
Now your Arduino is in DFU mode
The Device manager (in windows 7)
To return to the USB to serial converter mode, just disconnect and connect Arduino.
The upload of a firmware will be in the next article.

Monday, April 25, 2011

Facebook: Sort people by number of mutual friends(with Chrome support).

The script from the previous article can be used in Chrome also. Just click on the view raw and then click continue
Now install the script as an extension:
Now go to Facaebook->Find Friends
If the button doesn't appear, then refresh the page by pressing F5 (The script has an issue and sometimes the button isn't added, the temporary solution is refreshing the page until the problem will be fixed).
That's all.

Flightgear and Tx/Rx system

In the previous article the Flightgear's aircraft controlled using external program and in another article the Tx/Rx system connected to computer using Arduino. Today we will use those knowledges to connect Tx/Rx to Flightgear. Download the project from github and do the following steps.
1)Copy protocol files from Protocol/ to C:\Program Files (x86)\FlightGear\data\Protocol\
2)Compile and upload Rxreader/Rxreader.pde to the Arduino.
3)Connect Receiver to the Arduino
4)Run the C# program and connect to the Arduino and click to calibrate (this determines min-max values). When min-max values determined, finish the calibration.
5)Run Flightgear with the following arguments.
"C:\Program Files (x86)\FlightGear\bin\Win32\fgfs" ^
 "--fg-root=C:\Program Files (x86)\FlightGear\data" ^
 "--aircraft=Malolo1" ^
 "--generic=socket,out,10,127.0.0.1,49001,udp,outputprotocol" ^
 "--generic=socket,in,10,,49000,udp,inputprotocol" ^
 "--timeofday=noon"
6) Connect to Arduino, and connect the input and the output to Flightgear.
 
7)Try do not crash the airplane :)
That's all.

Wednesday, April 20, 2011

executable jpg files

On the following screenshot there are 3 files with the same thumbnail picture. The file extensions aren't hided. Now can you guess the formats of those files?

The first and the second files are executable, while the third file is an icon file. But, you can say, the file with "jpg" extension is a picture not an executable. It is true. But the problem is that the extension of "imggoofyrcs.jpg" isn't "jpg". How is it possible? The cause of this is the Unicode symbol \u202E(Right-To-Left Override):
The executable can open a picture to deceive a user and do anything in the background. The following code demonstrate how to open a picture and run a "calc" program.

Saturday, April 16, 2011

Facebook: Sort people by number of mutual friends

The Facebook's Find-Friends page lists people, whom Facebook thinks we may know. There are some ways to filter people by hometown or college (and etc...), but it lacks the simple ability to sort people by the number of mutual friends. Using Firefox and Greasemonkey add-on and the following script it can be done easily.
Add new user script in the Greasemonkey:
Add new user script.
Fill up the following information:
Fill-up.
Then copy the following script and past it to the newly opened sortby.user.js file and save it.

In the Facebook's Find Friends page now you can see a button near the hometown filter.
Click it and it will sort people by number of mutual friends.

That's all.

Tuesday, April 12, 2011

Arduino and Tx/Rx system

In the previous article the PWM signal was described, which used to control servo motors. Today we will use the following Transmitter/Receiver (Tx/Rx) and the Arduino to read PWM signals.
Tx/Rx manufactured by www.HobbyKing.com
The above Tx/Rx systems usually used for controlling airplanes, helicopters and other remote vehicles. This one has 6 channel, which means it can control 6 different motors (servos and other types).
In the following picture you can see 7 row of pins(6 channels + battery).
Receiver
This Tx/Rx system comes without any documentation, so the only way to get more information is to google the Internet. Actually I thought that the receiver gets it's power from the battery pins(I don't know why 3 pins) and generate appropriate PWM signals on all channels, but I discover the following:
If connect only(without battery connected) channel pins to appropriate Arduino pins(+5V to +5V, Gnd to Gnd, and Signal to digital port 2), then the receiver will work and on the signal pin it generates PWM signal, coming from transmitter. To read the signal, connect 2nd channel pins to Arduino appropriate pins(The 2nd channel corresponds to throttle). Connect signal pin to Arduino digital pin 2.

The Arduino has a PulseIn function, which can be used to read the PWM pulse width. The micros function returns the number of microseconds since the Arduino began running. Compile and upload the following code and run it then switch-on the transmitter.
Before switching on the transmitter, the time interval is about 100ms, which is equal to 50ms timeout time + Serial print times, and the pulse width is 0(no signal). When the transmitter switched-on, the pulse width is near to 1460us and time interval reduced to ~66ms, which now is equal to ~20ms period time + Serial print times.
Switching-on transmitter
And this is the screenshot of Serial output when the throttle is changed by moving joystick up and down.
Moving throttle joystick up/down
That's all.

Monday, April 11, 2011

Servo motors and PWM

In the previous article we use Arduino's Servo library to control servo motors. Today we will try to understand how Servo library works. The servo motors are controlled by digital PWM signals. Those signals are square waves with a period about 20-22ms. And the pulse width(usually ~0.5-2.5ms) is corresponds to the position of servo motor.
This a sample signal
There is another overloaded Servo.attach function (used to attach servo to the pin) with 3 arguments:
    servo.attach(pin, min, max) 
(min,max) are the pulse minimum and maximum widths in microseconds. Default values are 544us and 2400us(you can also check them in the <Arduino-dir>\libraries\Servo\Servo.h file, MIN_PULSE_WIDTH and MAX_PULSE_WIDTH macros). Most of hobby servo motors have those default values, but if your servo doesn't work, then you need to dig into the documentation to find out right values. This Servo library takes minimum 20ms for signal period: see <Arduino-dir>\libraries\Servo\Servo.h file:
    #define REFRESH_INTERVAL    20000 // minumim time to refresh servos in microseconds
That's all.

Wednesday, April 6, 2011

Flightgear: control aircraft externally

In the previous article the Flightgear program's some features were discussed. Today's topic will be about controlling aircraft through sockets from another program. There is a command line option "--generic" , which can be used for modifying items of property tree(see previous article, about http://localhost:1234).
Run the program with the following options.
The first generic argument means: Use sockets, for sending data out, 10 times a second, to the 127.0.0.1 machine(this is localhost's ip address), using the port 49001, use UDP protocol, the actual data which sent out are described in file "outputprotocol".
The second generic argument means: Use sockets again, for getting data from out, 10 times a second, skip the ip address, using the port 49000, use UDP protocol again, the coming data described in the file "inputprotocol".
If the program hangs, this means you are using the Flightgear version 2.0.0, which has a known bug and you need to downgrade to the version 1.9.1. Now if the hanging is over, then the program must give an error(see console's screen), because "outputprotocol" and "inputprotocol" files doesn't exists.
The following is "inputprotocol.xml" file's content, which describes 3 values, that the program will wait for input(aileron, elevator and throttle).
The following is "outputtprotocol.xml" file's content,which describes the same 3 values from input and plus one more (the speed of aircraft).
Now copy those files to the "C:\Program Files (x86)\FlightGear\data\Protocol" directory and run the program again. It will again give error(Error reading data), because no one send data to the input.
Now lets write a program in C#, which will send the input data to and receive output data from Flightgear. Add the controls to the main form as pictured in the screenshot:
We will use timer to send data in every 100ms(10 times in a second as described in the argument). This is sending part code: We will use threads to asynchronously get data from Flightgear. This is it:That's all.

Tuesday, April 5, 2011

Flightgear

Flightgear is open source flight simulator. It is weighted ~300MB for windows (relatively low compared to other simulators). It can be used not only for gaming. There are some R/C models, which can be used to practice on them. For example Malolo aircraft. Download and extract it to  C:\Program Files (x86)\FlightGear\data\Aircraft (Ubuntu: /usr/share/games/FlightGear/Aircraft/).
Then run the following from command line:
    "C:\Program Files (x86)\FlightGear\bin\Win32\fgfs" ^
        "--fg-root=C:\Program Files (x86)\FlightGear\data"  ^
        "--aircraft=Malolo1"
 or in Ubuntu
    fgfs --aircraft=Malolo1

Wait a minute, while the program finish loading, then you can drive the airplane using following keys.
    V                   : Change viewpoint
    Page-Up       : Increase throttle
    Page-Down  : Decrease throttle
    X                   : Zoom-in
    Shift-X          : Zoom-out
    Arrow keys   : Control elevator and aileron.
It is OK when you crash a plane just after a few seconds of flying :). Do some practice.

Flightgear has many useful features, and one of them is the ability to show the status of every components in the environment. Just run it adding the "--httpd=1234" argument and it creates a local web server. Navigating to http://localhost:1234 you can see a tree structure of all elements, which can be modified from browser also. For example start the program, change the viewpoint and navigate to http://localhost:1234/controls/engines/engine and click on throttle and change the value to 0.2.

Thursday, March 31, 2011

Linux and SETUID (SETGID, Sticky bit)

Every file in Linux has read, write and execute rights for the owner, group and others. Besides those attributes there are 3 extra attributes setuid, setgid and sticky bit.
1) The setuid attribute is meaningful for executable files. If this bit is set then the user ID would be set as that of the owner of executable rather than the current user. For example the sudo tool owner is root and the setuid bit is set on, and when another user run this program, it will be executed as root. If set off the setuid attribute, then the sudo tool will not work, because it will run as a normal user without root permissions.

 2) Setgid attribute is the analog to setuid, but for group ID.

3) In Linux sticky bit is meaningful for directories only(in old *nix systems it had another meaning also). If this bit is enabled on directory then the files in that directory may only be deleted or renamed by root or by their owner.

One more sample related to setuid

Tuesday, March 29, 2011

Arduino and Servo motors

Arduino has a Servo library which allows to control servo motors. Today we will use the following small servo motor and write a program, which read a angle value from Serial port and rotate servo motor according to it.
This is the source code of program

Compile and upload above code to Arduino, then connect control pin(gray wire) of Servo motor to Arduino pin 11, connect black wire to Gnd of Arduino and red wire to +5V. This is how it looks:

And this is a video demonstration of moving Servo 0 -> 90 -> 180 -> 0 -> 90:

Monday, March 28, 2011

Security bug in Ubuntu 10.10

Yes, Ubuntu also has security bugs. But this one can be used in the last steps of attacking. There are some requirements for this code to work. Attacker need to find a vulnerability in a process and run a shellcode and if that executable has CAP_SYS_ADMIN capability, then using this bug it can get root privileges.

To run this exploit download source from http://www.exploit-db.com/download/15944 and do the following steps:

How many G my car can pull?

In the previous article we study how to work with ADXL335 accelerometer. Today we will use it to measure car's acceleration. This is a sample program which get the values from sensor and send them through serial port to the computer. It measures every 20ms and do it 1000 times.

Now lets connect ADXL335 to the Arduino and then compile and upload the above code.
Sensor placed in such way that Z axis is directed to front of car.(You can see it in the picture, on top of red box).

I run the program, type something and press enter in the Serial Monitor and then drive as fast as possible and then brake the car. Copy the values to the Google Docs Spreadsheet and create a chart for the values of Z axis (in which direction the acceleration occurs). But before creating charts lets understand how those numbers map to the real acceleration values in g. The Z axis can be directed downward and measure value (+1g), then direct it upward and measure again(-1g) and taking account that the measured values dependance on acceleration is linear, calculate which value correspond to 0g and which interval correspond to 1g interval. I get following results (approximate results)
    0g --  355
    1g interval -- 70 interval
The measured values also contain a lot of noise, so we need to filter out them.

This is unfiltered chart: Z_i


This is filtered and converted to G chart: ((Z_i + Z_i+1) /2 - 355) / 70


This is filtered(another filter) and converted to G chart: ((Z_i + Z_i+1 + Z_i+2) / 3  - 355) / 705

In the above chart you can see the shift of gear from 1 to 2 and then brake. After car stops and acceleration is 0.

Friday, March 25, 2011

ASLR and Linux personality syscall

In the previous article we talk about ASLR and how to disable it. There was a way to disable ASLR for a single process using setarch command. Now we are going to understand how setarch command do that. Lets use strace command to trace all system calls of setarch command with and without -R option

There are a lot of differences, because of the ASLR: In the log there are a lot memory addresses and they will be different. Now lets disable it for all processes and then do above steps again to filter out memory differences.
Now we see that there is a system call named personality. It is difficult to understand from the man personality what this syscall actually do. So we can get a information from include file of personality syscall(in case of Ubuntu 10.10 it located at /usr/include/sys/personality.h). Here it is:
There is enum ADDR_NO_RANDOMIZE equal to 0x0040000 which passed in as an argument in personality in above difference logs. So we understand that we can disable the process's ASLR by calling personality syscall with ADDR_NO_RANDOMIZE argument. Lets modify the program from previous article and check is this works.
Enable ASLR by echo 2 | sudo tee /proc/sys/kernel/randomize_va_space. Run above code twice and when they wait for input, dump the memory maps (get pid from htop and then cat /proc/pid/maps) and compare them: it works, the maps are the same. You can also comment out the line containing personality and get different memory maps.

Address space layout randomization (ASLR)

ASLR is a technique which randomly arranges the libraries, heap, stack and other pages in the memory in random positions. This technique designed for standing against security attacks. If the ASLR is disabled, the memory addresses of libraries and the stack are predefined, so the vulnerable codes(shellcodes) can use these information and directly call library functions. To check if the ASLR is enabled in the system we can run some program twice and compare memory maps.

The memory positions are different, that means the ASLR is enabled. From the debugging point of view it sometimes distrurbs and we need to disable it. There are 2 ways(known to me) to disable ASLR.
1) Disable ASLR using setarch command


2) Disable ASLR for entire system

Thursday, March 24, 2011

ptrace -- Linux system call

In the previous article the strace command observed, today we are going to understand how the strace tool works and write a simple system tracer program to trace system calls of ls program.
At first let strace the ls program
    strace -o ls.strace ls

To know which system calls the strace uses lets run it on itself. 
    strace -o strace.strace strace ls

As we can see the strace use a lot of system calls, but the one of them (ptrace) appears a lot in the log. The ptrace provides a means to get information from the child process (see man ptrace).The following simple program uses the ptrace to trace system calls of ls program



We also need to know the names of system calls by their syscall number. We can extract that information from the sources of strace. The file "strace-4.6/linux/x86_64/syscallent.h" contains the information that we need, we can parse it and get the list of system calls arranged by syscall number (see the instructions in the sources).

Wednesday, March 16, 2011

Strace -- tool for system call tracing

For tracing system calls of a program, there is a "strace" command in Linux. This program comes with the most of Linux distributions. If it is not present in your system, you can download it from http://sourceforge.net/projects/strace/, build and install.
Lets try run the hcidump and see which system calls it use:
    sudo strace -o output hcidump -i hci0
Do some bluetooth related things(search a device) and see the output file

As we can see, hcidump uses socket related system calls(socket, bind, recvmsg and etc...) for getting bluetooth data, ioctl system call(for controlling bluetooth device), write system call (guess why :-) ), poll system call (which used for waiting for a socket IO events).
There is "-e trace=" option, which trace only specified set of system calls, for example
    sudo strace -o output -e trace=socket,write,poll hcidump -i hci0
will trace only system calls socket, write and poll.

And at last there is a good syntax highlighter in the "vim" for strace's output
(In the case if vim doesn't automatically enable it -- :setf strace).

Sunday, March 6, 2011

Bug in hcidump

Try to run the following command:
  $ sudo hcidump -i aaa
Instead of giving an error that there is no device with a name "aaa", hcidump uses the "hci0" device. The first thing that comes to mind is maybe hcidump uses "hci0" device by default if the specified device not found, but when I try to run the following:
  $ sudo hcidump -i aaa123
It gives an error:
  Can't open device: No such device
So what is the reason of such behavior. To find out it, I review the argument parsing part of the source code (as hcidump is open source) and find out the following.
To download the source code of hcidump (version 1.42, used in Ubuntu 10.10) 
  $ git clone git://git.kernel.org/pub/scm/bluetooth/bluez-hcidump.git  # get the sources
  $ git checkout -b new 1.42                                    # get the version 1.42

The code of input arguments parsing is located in file "src/hcidump.c" starting at line 1002. The device name's parsing code is located between 1004 1010 lines:


As you can see the reason of the unusual behavior is in the following line:
    device = atoi(optarg + 3);
which didn't check the correctness of input (work for "hci[0-9]" like names only).

Thursday, March 3, 2011

How to build the latest hcidump.

In the previous article the "hcidump" was used for dumping bluetooth protocol packets. The binary package of "hcidump" is exists for Ubuntu and other widespread Linux distribution, but what about other distributions. For them we need to compile and install it from sources. So the following instructions will be useful:

1)Download the source code from the official site or checkout sources from repository. We will choose the second one, because it contains the latest patches and changes (sometime new bugs :( also ). "hcidump" uses Git source control system, so the git package is needed (Ubuntu: sudo apt-get install git). To check-out the sources run the following
$git clone git://git.kernel.org/pub/scm/bluetooth/bluez-hcidump.git

2)Enter "bluez-hcidump" directory. Now you need to configure the sources and then build them. It uses GNU build system, so we need to follow standard steps.
GNU build system(source: Wikipedia).
Before compiling ensure that you have the latest "BlueZ" library installed.
Steps: 
$ aclocal                                     # Generate "aclocal.m4" file
$ autoheader                              # Generate "config.h.in"
$ autoconf                                  # Generate "configre" file
$ automake --add-missing          # Generate "Makefile.in" file and add missing files
$ ./configure                               # Configure
$ make                                        # Build hcidump
$ make install                             # Install

Now you have the latest hcidump tool.

Monday, February 28, 2011

Bluetooth HCI

There are various protocols used in Bluetooth. One of them is the HCI(Host/Controller interface) protocol, which is used in the communication between the host stack(BlueZ or Affix) and the controller(Bluetooth chip). Today using the "scanner" program from the previous article and the "hcidump" tool we will see how the HCI protocol packets look like. The "hcidump" tool dumps HCI data coming from and going to a Bluetooth controller (Ubuntu users can install it by "sudo apt-get install bluez-hcidump"). To view dumped files we need the wireshark program also (Ubuntu users: sudo apt-get install wireshark).
Run hcidump in background mode and then run the "scanner"
$ sudo hcidump -i hci0 -w dump &
$ ./scanner

By the -i option Bluetooth device is specified and by the -w option the output file is specified.
When "scanner" finish, kill the background hcidump and then open "dump" file with wireshark program:
WireShark 
In the screenshot you can see two type of HCI packets: HCI_CMD -- computer sends commands to the controller and HCI_EVT -- the controller sends the result. The info column of HCI_CMD packets shows the command sent within a packed. Two type of commands shown in screenshot: "Inquiry" (op code: 0x0401) and "Remote Name Request" (op code: 0x0419). They are the commands sent when the "hci_inquiry" and the "hci_read_remote_name" functions where called(see the source code of "scanner").

The selected packet is a description of the device find by the scanner (as we can see from the fields "BD_ADDR" and "Class of Device" it is a Nokia mobile phone).

Sunday, February 27, 2011

Linux and Bluetooth

There are 2 widespread Bluetooth stack implementations in Linux: BlueZ and Affix. Today we will use the BlueZ library for writing a simple "nearby device finder" program. Before you start, make sure you have installed the necessary Bluetooth packages. Ubuntu users can install them by running:
    sudo apt-get install bluez libbluetooth-dev
At first we need to include the following BlueZ header files
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

To work with a Bluetooth device we need a device id, which can be retrieved by "hci_get_route"  function: if pass NULL argument to "hci_get_route", it will return the id of first available device, or -1 if there isn't any. Now we can use "hci_get_route" function, which search the nearby Bluetooth devices and return basic information about them in a "inquiry_info" structure:
typedef struct {
  bdaddr_t  bdaddr;
  uint8_t   pscan_rep_mode;
  uint8_t   pscan_period_mode;
  uint8_t   pscan_mode;
  uint8_t   dev_class[3];
  uint16_t  clock_offset;
} __attribute__ ((packed)) inquiry_info;

The "bdaddr" member contains the address of a device (it is like a MAC address of network devices, by the way they have the same syntax).
There are 2 functions to convert between strigns and "bdaddr_t" structures.
int str2ba( const char *str, bdaddr_t *ba );
int ba2str( const bdaddr_t *ba, char *str );
The address of remote Bluetooth device is enough to work with it, but the end users usually work with the device names. The "hci_read_remote_name" function retrieve the name of remote device using it's address. But "hci_open_dev" require an open socket. The "hci_open_dev" function opens an appropriate Bluetooth socket. And at last we can use "hci_open_dev" function to get the name and address of the local Bluetooth device.
See the source code for details:

Tuesday, February 15, 2011

Arduino and EEPROM

  EEPROM is a non-volatile memory on the Arduino. It's like a HDD in the computer, can hold the data when board is turned off, but has too little memory :(. The EEPROM size of Arduino Duemilanove's Atmega328 is only 1024 byte.
  Arduino IDE has simple EEPROM library, which has only 2 functions: "read" and "write". Lets write a demo program which will save to EEPROM anything received from serial port and if the 's' symbol is received it will return all stored symbols.

Monday, February 14, 2011

ADXL335 Accelerometer

Accelerometer is a sensor that measure linear acceleration. Today we will use ADXL335 accelerometer, we will write a program to display the measured values of acceleration of all 3 axes.
ADXL335 on a board(Manufactured by Sparkfun.com)
You can see axis scheme on the board, the x and y axises directions are clear, and the z axis direction is point out of the board. Remember this sensor has a sensing range of +/-3g, so you can't measure a higher accelerations :). But it is not a big disadvantage, because the calculation shows that more than 100 km/h we can get during 1 second of 3g acceleration. If you want to check it but you are lazy to do, you can use http://www.wolframalpha.com(3 * gravitational acceleration * 1 second in km/h).
The interface of this device is analog: The voltages on X(Y,Z) port depends on the linear acceleration throughout X(Y,Z) axis. The Arduino board has 6 analog-in ports, we can use 3 of them(0,1,2) to connect to X,Y,Z ports of ADXL335.
Analog ports

So lets open the Arduino IDE and write a simple program, which will periodically read the values on analog ports and send trough the Serial port.

In this program analogRead function read the voltage on the pin and return the integer value between 0 and 1023.
On the computer side we will read the information coming through Serial port an show the values on 3 horizontal progress bars.

This is C# code of program

Be careful, connect ADXL335 to the Arduino board, before connecting them to the PC, otherwise the board will hang and only solution is reconnecting.

This is a short video how it runs.