Danilo's Tech Blog

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Thursday, 10 January 2013

How to port Mozilla SpiderMonkey 1.7 to Android

Posted on 07:47 by Unknown
Another third-party package I needed to cross-compile for Android was Mozilla's SpiderMonkey 1.7 Javascript engine. I found two issues here:

  1. When configuring SpiderMonkey the makefile tries to build two executables (jscpucfg and jskwgen) and then runs them to generate two  configuration header files (jsautocfg.h and jsautokw.h, respectively). The problem when using the Android NDK cross-compiler is that these two executables can only be run on the Android target (for example an ARM processor), while I'm cross-compiling my build from a Linux Ubuntu 12.04 machine with an x86_64 processor architecture. So you get an error that you cannot execute these files on the host machine.
    I solved this problem by copying the two executables to an Android device (Samsung Galaxy S III) using scp and the SSHDroid application, and generating the two header files there:

    $ jscpucfg > jsautocfg.h
    $ jskwgen > jsautokw.h

    then I copied the two files back to my node on my Ubuntu machine and saved in the source trunk under the config sub-directory. Then I changed the makefile to skip generating these two header files when cross-compiling for Android and get them instead from the config sub-directory.
  2. The SpiderMonkey jsnum.c file generates the following error when cross-compiled for Android:

    js-1.7/jsnum.c: In function 'js_InitRuntimeNumberState':
    js-1.7/jsnum.c:578: error: 'struct lconv' has no member named 'thousands_sep'
    js-1.7/jsnum.c:578: error: 'struct lconv' has no member named 'thousands_sep'
    js-1.7/jsnum.c:580: error: 'struct lconv' has no member named 'decimal_point'
    js-1.7/jsnum.c:580: error: 'struct lconv' has no member named 'decimal_point'
    js-1.7/jsnum.c:582: error: 'struct lconv' has no member named 'grouping'
    js-1.7/jsnum.c:582: error: 'struct lconv' has no member named 'grouping'
    gmake[2]: *** [js-1.7.dir/jsnum.c.o] Error 1

    This is caused by the fact that the lconv structure in locale.h shipped with the Android NDK is stubbed with the following comment:

    #if 1 /* MISSING FROM BIONIC - DEFINED TO MAKE libstdc++-v3 happy */
    struct lconv { };
    struct lconv *localeconv(void);
    #endif /* MISSING */

    To solve this problem I applied the following patch to jsnum.c and I was able to successfully cross-compile SpiderMonkey 1.7 for Android.

    --- a/jsnum.c   2013-01-10 10:37:54.413800695 -0500
    +++ b/jsnum.c   2013-01-10 10:06:49.432752061 -0500
    @@ -573,13 +573,28 @@ js_InitRuntimeNumberState(JSContext *cx)
         u.s.lo = 1;
         number_constants[NC_MIN_VALUE].dval = u.d;
     
    -    locale = localeconv();
    -    rt->thousandsSeparator =
    -        JS_strdup(cx, locale->thousands_sep ? locale->thousands_sep : "'");
    -    rt->decimalSeparator =
    -        JS_strdup(cx, locale->decimal_point ? locale->decimal_point : ".");
    -    rt->numGrouping =
    -        JS_strdup(cx, locale->grouping ? locale->grouping : "\3\0");
    +    /* Copy locale-specific separators into the runtime strings. */
    +    const char *thousandsSeparator, *decimalPoint, *grouping;
    +#ifdef HAVE_LOCALECONV
    +    locale = localeconv();
    +    thousandsSeparator = locale->thousands_sep;
    +    decimalPoint = locale->decimal_point;
    +    grouping = locale->grouping;
    +#else
    +    thousandsSeparator = getenv("LOCALE_THOUSANDS_SEP");
    +    decimalPoint = getenv("LOCALE_DECIMAL_POINT");
    +    grouping = getenv("LOCALE_GROUPING");
    +#endif
    +    if (!thousandsSeparator)
    +        thousandsSeparator = "'";
    +    if (!decimalPoint)
    +        decimalPoint = ".";
    +    if (!grouping)
    +        grouping = "\3\0";
    +
    +    rt->thousandsSeparator = JS_strdup(cx, thousandsSeparator);
    +    rt->decimalSeparator = JS_strdup(cx, decimalPoint);
    +    rt->numGrouping = JS_strdup(cx, grouping);
     
         return rt->thousandsSeparator && rt->decimalSeparator && rt->numGrouping;
     }

    Of course you would define HAVE_LOCALECONV only for regular builds but not for Android cross-compilations, so that you could either pass your own definitions for the locale thousands separator, decimal point or locale grouping via environment variables, or use the above defaults.
Read More
Posted in Android, GNU, Javascript | No comments

Wednesday, 9 January 2013

How to inspect expanded C macros with gcc/gcc+

Posted on 12:04 by Unknown
Sometimes you get compilation errors in gcc/g++ and you'd like to inspect the output from the C compiler pre-processor to figure out why certain macros were expanded in such as way to cause an error.
The solution is simply to remove the -o and -c options from your gcc/g++ command line and replace it with

gcc/g++ -E -dD

this will generate on your terminal only the C pre-processor output that is eventually fed to the C/C++ compiler.

For example you are trying to compile Mozilla SpiderMonkey 1.7 and one of  the compiler lines is the following:

/usr/bin/gcc  -Djs_1_7_EXPORTS -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R -DX86_LINUX -D_IEEE_LIBM -DJS_EDITLINE -DEDITLINE -DHAVE_VA_COPY -DVA_COPY=va_copy -DPIC -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX -DHAVE_STDLIB -DUNIQUE_HISTORY -O3 -DNDEBUG -fPIC -I../js-1.7  -fPIC -o CMakeFiles/js-1.7.dir/jsarena.c.o   -c js-1.7/jsarena.c

To see the expanded C macros run the following command:

 /usr/bin/gcc  -E -dD -Djs_1_7_EXPORTS -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R -DX86_LINUX -D_IEEE_LIBM -DJS_EDITLINE -DEDITLINE -DHAVE_VA_COPY -DVA_COPY=va_copy -DPIC -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX -DHAVE_STDLIB -DUNIQUE_HISTORY -O3 -DNDEBUG -fPIC -I../js-1.7  -fPIC  js-1.7/jsarena.c



Read More
Posted in GNU, Linux | No comments

Sunday, 6 January 2013

Upgrading mid-2007 24in iMac with an SSD and a 2.5in HDD in the optical bay

Posted on 18:40 by Unknown
I own a mid-2007 24in iMac with a 2.4 GHz Intel Core 2 Duo processor, 4GB of DDR2 DRAM, running Mac OS Mountain Lion, and for the past few months the computer was getting slower and slower, and when I was running Windows XP in VMWare Fusion, the machine was often swapping, bringing the iMac to a crawl. Finally I decided to upgrade my iMac by installing an SSD. Two years ago I replaced the Western Digital 500 GB hard drive (that failed on me one day by giving me the gray screen of death at boot time), with a 1 TB WD caviar green which I almost filled since then (about 750 GB used).
So I wanted the fast SSD drive but also to maintain the 1 TB of space available. The solution I adopted (found on several posts on the internet) was to replace the existing SATA HDD with an SSD, and replace the optical drive with a PATA to SATA adapter hosting a 2.5in HDD. To avoid the swapping I also replaced one of the 2 GB memory modules with a new OWC 4GB module, bringing the total available memory to 6GB.

Hardware Parts

This is the list of hardware components I ended up buying for this upgrade:

  • Crucial M4 CT064M4SSD2 2.5" 64GB SATA III MLC Internal Solid State Drive (SSD)
  • SilverStone SDP08 2 x 2.5" to 3.5" Bay Converter
  • Western Digital Scorpio Blue WDBABC0010BNC-NRSN 1 TB 2.5' Internal Hard Drive
  • MCE OptiBay Enclosure for SATA Hard Drive for iMac
  • 4.0GB PC-5300 DDR2 667MHz SO-DIMM 200 Pin Memory Upgrade Module

Hardware Installation

Here is the picture of the tools I used to perform the upgrade (grounding wrist band, 6 Pc. mini torx screwdriver set, spudgers, vacuum cups, philips screwdriver.



I followed the instructions to replace the hard drive and the optical bay from the iFixit web site.
The following picture shows the iMac internal components.



The old 1TB caviar green HDD is shown in the following picture. The idea was to replace it with the SSD mounted on the 2.5'' to 3.5'' bay converter.



This picture shows instead the Apple optical drive (superdrive).


I removed the optical drive and replaced it with the 1TB WD Blue HDD mounted on the MCE OptiBay enclosure as shown in the following picture. I also put a piece of foam in the enclosure gap (top of picture) to prevent the HDD from moving.


Then I installed the Crucial M4 SSD inside the SilverStone 2.5" to 3.5" Bay Converter in the bottom position (there is room to install two SSD or two 2.5'' HDD), in order to align the SATA and power connectors with the iMac motherboard.




The following picture shows the newly installed SSD on the top left, and the WD Blue HDD inside the OptiBay enclosure on the bottom right. Notice I attached the thermal sensor for the SSD directly on the metal frame of the bay converter, and used tape to make sure it stays in position.



All the hardware parts described above fitted perfectly in my iMac and I didn't have to do anything special to install them except for adding the piece of foam in the OptiBay enclosure to prevent the HDD from moving around.

Software Configuration

At this point my iMac had two new unformatted disk drives and my original HDD was sitting on my desk. What I had in mind was to install Mac OS on the Crucial M4 SSD, and put the users on the WD Blue HDD. In fact 64 GB are not enough to store the users directories where for example pictures and movies take a lot of disk space. To restore the system I then followed this procedure.
  • I took the original WD caviar green HDD and installed it in a Rosewill external SATA enclosure I had laying around. Then I connected the external SATA enclosure to the iMac via an USB cable.
  • I powered up the iMac holding the option button. This gave me the option to boot into Mountain Lion from the external WD Caviar Green HDD (volume name Macintosh HD).
  • I logged in and opened the Disk Utility application. Selected the Crucial M4 disk, clicked on the Erase tab and formatted the disk by selecting the Mac OS Extended (journaled) format and naming the volume Macintosh SSD.
  • In a similar way I erased the WD Blue HD disk and named the volume Macintosh HD Users. At the end of this procedure, Disk Utility showed the following on the screen:

  • Then I ran Carbon Copy Cloner and copied all directories from the external Macintosh HD except the /Users directory to the Crucial M4 on volume Macintosh SSD (it is simple to do this since Carbon Copy Cloner allows you to select individual directories to copy from the source). I ended up copying about 32 GB to the Macintosh SSD volume, which took about 1 hour. 
  • I ran Carbon Copy Cloner again but this time for source I selected the /Users directory only from the external Macintosh HD, and Macintosh HD Users for destination. To copy 693 GB Carbon Copy Cloner took about 7 hours and 47 minutes.
  • (If you don't want to use Carbon Copy Cloner, you can copy the files directly using the ditto command. For example to clone the /Users directory: 

  • # sudo ditto /Volumes/Macintosh\ HD/Users /Volumes/Macintosh\ HD\ Users/Users/
    )

  • I then opened the Terminal app, logged in as root and created a symbolic link to the new location of the /Users directory:

  • # sudo su -
    # cd /Volumes/Macintosh\ SSD
    # ln -s /Volumes/Macintosh\ HD\ Users/Users/ Users
At this point I rebooted the iMac and when it came back all my original logins with their setting were magically preserved. MacOSX now boots in 13 seconds, and opening applications is almost instantaneous. Now I still had to do some tweaks to make the new setup even better. I followed the suggestion from Martin's blog (Optimizing MacOS X Lion for SSD).
  1. I went to System Preferences, clicked on Users & Groups, clicked the lock icon to unlock the advanced editing. Once unlocked, I right-clicked on each user account and chose Advanced Options from the pop-up menu. Once in the Advanced Options dialog, I changed the Home directory of the user from /Users/user-name to the new location (/Volumes/Macintosh\ HD\ Users/Users/user-name).
  2. I installed and enabled TrimEnabler from this web site.
  3. I set the noatime flag to prevent MacOS from updating the SSD file system every time a file is accessed.
  4. I used the WD Blue HDD for temporary files.

    sudo ditto /private/tmp /Volumes/Macintosh\ HD\ Users/private/tmp
    sudo rm -rf /private/tmpsudo ln -s /Volumes/Macintosh\ HD\ Users//private/tmp /private/tmp
I rebooted the iMac another time and verified that Trim was working, the root file system was mounted with the noatime flag and that temporary files were going to the HDD drive instead of the SSD.
Given new life to an old machine. I'm pretty happy now.
Read More
Posted in Apple, iMac, MacOSX | No comments

Tuesday, 18 December 2012

How to Cross-Compile libiconv for Android

Posted on 11:57 by Unknown
If your legacy C/C++ code includes <iconv.h> to convert the encoding of characters from one coded character set to another, and you need to cross-compile it with the Android NDK, you will get the following error:

   error: iconv.h: No such file or directory

In fact there is currently no iconv.h available in the Android NDK and you will have to port libiconv to Android yourself.
I successfully used the following instructions to cross-compile libiconv.so for Android.

Get the source code for libconv-1.13.1:
 
   $ wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz
 
Unzip and untar the file:

   $ tar zxvf libiconv-1.13.1.tar.gz
 
Patch libcharset.c using the following patch file (or else you will get another error: : langinfo.h: No such file or directory) :
 
   $ echo "diff --ignore-file-name-case -wuprN libiconv-1.13.1.orig/libcharset/lib/localcharset.c libiconv-1.13.1/libcharset/lib/localcharset.c
--- libiconv-1.13.1.orig/libcharset/lib/localcharset.c  2009-06-21 07:17:33.000000000 -0400
+++ libiconv-1.13.1/libcharset/lib/localcharset.c       2012-12-18 10:20:27.000000000 -0500
@@ -44,7 +44,7 @@
 # endif
 #endif

-#if !defined WIN32_NATIVE
+#if !defined(WIN32_NATIVE) && !defined(__ANDROID__)
 # if HAVE_LANGINFO_CODESET
 #  include <langinfo.h>
 # else
@@ -328,7 +328,7 @@ locale_charset (void)
   const char *codeset;
   const char *aliases;

-#if !(defined WIN32_NATIVE || defined OS2)
+#if !(defined WIN32_NATIVE || defined OS2 || defined __ANDROID__)

 # if HAVE_LANGINFO_CODESET " > iconv.patch

   $ patch -b -p0 < ./iconv.patch


Run the configure script and generate iconv.h:

   $ cd libiconv-1.13.1
   $ ./configure

Create a jni sub-directory:
 
$ mkdir jni
 
And save the following lines in jni/Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
TARGET_ARCH_ABI := armeabi-v7a
LOCAL_MODULE := iconv
LOCAL_CFLAGS := \
-Wno-multichar \
-D_ANDROID \
-DLIBDIR="\"c\"" \
-DBUILDING_LIBICONV \
-DIN_LIBRARY
LOCAL_C_INCLUDES := \
../libiconv-1.13.1 \
../libiconv-1.13.1/include \
../libiconv-1.13.1/lib \
../libiconv-1.13.1/libcharset/include
LOCAL_SRC_FILES := \
../libiconv-1.13.1/lib/iconv.c \
../libiconv-1.13.1/lib/relocatable.c \
../libiconv-1.13.1/libcharset/lib/localcharset.c
include $(BUILD_SHARED_LIBRARY)
 
Finally cross-compile iconv using the ndk-build tool:

   $ cd jni
   $ ndk-build V=1
If everything goes well, you will find iconv.h under libiconv-1.13.1/include and libiconv.so under libs/armeabi.
Read More
Posted in Android | No comments

Tuesday, 4 December 2012

Configuring the Apple Airport Extreme with Verizon FIOS

Posted on 19:51 by Unknown
I have Verizon FIOS triple-play service and I love the TV picture quality and internet speed and reliability, but I don't like Verizon's solution to my Parental Control needs.
So I've decided to buy an Airport Extreme Base Station (AEBS) from Apple, but when I went to set it up, it configured itself for bridged mode since the Verizon modem is also a router and the Airport Utility decided not to have a double NAT configuration. Anyway by doing so you loose the capability of having a guest network with the Airport Extreme since it dummies itself down from a full fledged router to a simple level-2 switch.
So I managed to manually set it up in DHCP/NAT mode even though it is initially complaining about a double NAT configuration (one from the Verizon router and one from the AEBS), but least I gained my guest network back (at the time of this post it is not possible to configure a guest network with the Verizon router). 


Hardware Configuration


Apple Router: AirPort Extreme Base Station, Part Number: MD031LL/A 




Verizon Modem/Router: Actiontec MI424WR Rev. I
  • I used a CAT6 Patch cable to connect the AEBS Internet WAN port to Ethernet Port 1 of the Actiontec. This setting allows the two routers to communicate at wire speed of up to 1 GB per second.




Software Configuration



Here is the step by step procedure to set up the Airport Extreme I ran from an iMac running Mountain Lion.




  • Click on the picture of the Airport Extreme base station: a popup window will show an Edit button
  • Click on the Edit button
  • Click on the Network tab and select "DHCP and NAT" from the Router Mode
  • Click on the Network Options button and select "10.0" for the IPv4 DHCP Range, and "172.16" for the Guest IPv4 DHCP Range. Click on the Save button (see picture below)






  • Click on the Update button: this will reset the AEBS and cause a solid yellow light with a status of Double NAT. The AEBS will advise you to switch back to bridge mode
  • Click on the Double NAT Status pull-down menu and select Ignore: after another reboot the AEBS should come up with a solid green color


Regarding the Actiontec configuration, I left it as is, except for disabling the wireless mode to avoid interference with the AEBS.

  • With an internet browser log on to http://192.168.1.1 using the login and password printed on the bottom of the MI424WR modem/router.
  • Click on the Wireless Settings icon:

Wireless
Settings
  • Click on Basic Security Settings from the left panel
  • Click on Off from the 1. Turn Wireless ON form entry
  • Click on the Apply button to disable wireless

Considerations

Having the Verizon DHCP server using the 198.168.1.xxx IP addresses range and the AEBS the 10.0.1.xxx range will keep you sane and prevent confusions in your mind about which sub-network you are connected to. 
In any case these two sub-networks are completely separated and invisible from the Internet and you cannot have a device connected to one subnet talk to another device on the other subnet (unless you start configuring forwarding ports on the AEBS of course). This is OK since I plan to keep all of my computers and devices on the subnet controlled by the AEBS in order to have access control over each device.
To my disappointment the Airport Utility version 6.1 used to configure the AEBS is probably one the worst application I ever used to set up a router. It's not intuitive and worst of all it doesn't show who's connected to your network (or at least it doesn't show all the connected devices). In fact it only shows wireless clients in a weird fashion (by hovering over the base station picture), but no sign of any device connected through the Gigabit ethernet ports. By the way the list of wireless client is dynamic and you cannot even copy/paste the MAC addresses to add later to the access control table. I ended up switching to the previous version of Airport Utility (version 5.6 - as suggested by several people on the Internet) since with that you can still get a list of all devices connected to the AEBS from the Advanced->Logs and Statistics->DHCP Clients tab.

Still for parental control AEBS only has a time-based table where you can setup a schedule on a per MAC address basis. So I still had to resolve the problem of preventing my kids from hitting questionable web sites. I solved that by setting the OpenDNS servers for primary and secondary DNS servers in my Verizon router. OpenDNS offer a basic parental control filter based on categories. But I found that is is adequate for my needs.

Read More
Posted in Apple, DHCP, GPON, Network, Router | No comments

Tuesday, 20 November 2012

Python For Android (Py4A)

Posted on 07:01 by Unknown
A better solution for cross-compiling Python for Android is to use the Py4A project which is made to be used together with SL4A (Scripting Layer For Android). If you are only interested in the Python interpreter and the runtime Python library, you can also use it standalone.
Get a local copy of the source code using  the following command:

   $ hg clone https://code.google.com/p/python-for-android/

Just focus on the python-build subdirectory and make sure the  python-build/python-src subdirectory is not present (remove it if it came with the Mercurial repository, or else the compilation will fail).
Set up your environment so that the python-for-android build script can pick up the ndk-build script from the Android NDK:

  $ export ANDROID_NDK_ROOT=/home/<your-directory>/android-ndk-r8
  $ export PATH=$ANDROID_NDK_ROOT:$PATH

Finally build Python for Android by issuing the following command:

  $ cd python-for-android/python-build
  $ rm -rf python-src
  $ bash build.sh

Note that on my Ubuntu 12.04 machine I had initially the following compilation error:

Traceback (most recent call last):
  File "build.py", line 161, in <module>
    os.path.join(pwd, 'output.temp', 'usr'))
  File "build.py", line 89, in zipup
    zip_file = zipfile.ZipFile(out_path, 'w', compression=zipfile.ZIP_DEFLATED)
  File "/home/danilo/python-for-android/python-build/host/lib/python2.6/zipfile.py", line 660, in __init__
    "Compression requires the (missing) zlib module"
RuntimeError: Compression requires the (missing) zlib module


I identified the problem in having the zlib library in my system installed under /lib/x86_64-linux-gnu/ instead of one of the traditional lib directories covered by the Python setup.py script. Also on my system I only had libz.so.1 and not libz.so. So to fix both problems I just created a symlink in the standard /usr/lib directory as follows:

  $ cd /usr/lib
  $ sudo ln -s /lib/x86_64-linux-gnu/libz.so.1 libz.so

With this fix the build.sh script was able to successfully build the zlib module for the host environment and create the following zipped files:

  • python_extras_r14.zip
  • python-lib_r16.zip
  • python_r16.zip
  • python_scripts_r13.zip

Of these I only used the python_r16.zip which contains the stripped python interpreter and the runtime libraries, and the python-lib_r16.zip which contains the include header files such as Python.h that can be used to compile Python bindings at development time.


Read More
Posted in Android, Linux, Python | No comments

Monday, 5 November 2012

Arduino and 7-segment LED counter driven by two tactile switches

Posted on 14:16 by Unknown
I have posted on YouTube a couple of videos about a project I made with the Arduino prototype board. The circuit uses an Arduino mini and has a simple gear counter based on a 7-segment LED and controlled by two switches. It can be mounted on your bike and used for example to visualize which gear you are in at any time.

If you are interested in the schematics I can send you the PCB Artist version by email. The Arduino code is instead available below.

/*
Blink

Turns on an LED on for one second, then off for one second, repeatedly.

The circuit:
* LED connected from digital pin 13 to ground.

* Note: On most Arduino boards, there is already an LED on the board
connected to pin 13, so you don't need any extra components for this example.


Created 1 June 2005
By David Cuartielles

http://arduino.cc/en/Tutorial/Blink

based on an orginal by H. Barragan for the Wiring i/o board

*/

#define BUTTON_DOWN 10
#define BUTTON_UP 12

int ledPinA = 6; // LED connected to digital pin 3
int ledPinB = 9; // LED connected to digital pin 4
int ledPinC = 4; // LED connected to digital pin 5
int ledPinD = 3; // LED connected to digital pin 6
int ledPinE = 2; // LED connected to digital pin 7
int ledPinF = 7; // LED connected to digital pin 8
int ledPinG = 8; // LED connected to digital pin 9
int ledPinDP = 5; // LED connected to digital pin 10

int val_down = 0;
int old_val_down = 0;
int val_up = 0;
int old_val_up = 0;
int state = 0;
int gear = 1;

// The setup() method runs once, when the sketch starts

void setup() {
pinMode(BUTTON_DOWN, INPUT);
pinMode(BUTTON_UP, INPUT);

// initialize the digital pin as an output:
pinMode(ledPinA, OUTPUT);
pinMode(ledPinB, OUTPUT);
pinMode(ledPinC, OUTPUT);
pinMode(ledPinD, OUTPUT);
pinMode(ledPinE, OUTPUT);
pinMode(ledPinF, OUTPUT);
pinMode(ledPinG, OUTPUT);
pinMode(ledPinDP, OUTPUT);

// initialize serial communication:
Serial.begin(9600);
}

void led0()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinDP, HIGH);
}

void led1()
{
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinDP, HIGH);
}

void led2()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, HIGH);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led3()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led4()
{
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led5()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led6()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led7()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinDP, HIGH);
}

void led8()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void led9()
{
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinDP, HIGH);
}

void ledDP()
{
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, HIGH);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinDP, LOW);
}

void setLed(int number)
{
switch (number) {
case 0:
ledDP();
break;
case 1:
led1();
break;
case 2:
led2();
break;
case 3:
led3();
break;
case 4:
led4();
break;
case 5:
led5();
break;
case 6:
led6();
break;
case 7:
led7();
break;
case 8:
led8();
break;
case 9:
led9();
break;
}
}

// the loop() method runs over and over again,
// as long as the Arduino has power

void oldloop()
{
ledDP();
delay(1000); // wait for a second
led0();
delay(1000); // wait for a second
led1();
delay(1000); // wait for a second
led2();
delay(1000); // wait for a second
led3();
delay(1000); // wait for a second
led4();
delay(1000); // wait for a second
led5();
delay(1000); // wait for a second
led6();
delay(1000); // wait for a second
led7();
delay(1000); // wait for a second
led8();
delay(1000); // wait for a second
led9();
delay(1000); // wait for a second
}

void loop()
{
val_up = digitalRead(BUTTON_UP);
if ((val_up == HIGH) && (old_val_up == LOW)) {
gear += 1;
Serial.print("gear number: ");
Serial.println(gear, DEC);
delay(100);
}
old_val_up = val_up;

val_down = digitalRead(BUTTON_DOWN);
if ((val_down == HIGH) && (old_val_down == LOW)) {
gear -= 1;
Serial.print("gear number: ");
Serial.println(gear, DEC);
delay(100);
}
old_val_down = val_down;

if (gear >= 6) {
gear = 6;
}
if (gear <= 1) {
gear = 1;
}

setLed(gear);
}

Read More
Posted in Arduino | No comments
Newer Posts Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • Python For Android (Py4A)
    A better solution for cross-compiling Python for Android is to use the Py4A project which is made to be used together with SL4A (Scripting L...
  • Arduino and 7-segment LED counter driven by two tactile switches
    I have posted on YouTube a couple of videos about a project I made with the Arduino prototype board. The circuit uses an Arduino mini and ...
  • Transferring Files from a computer to your Android device
    Android devices have file systems similar to regular computers. Subject to permissions restrictions, we can transfer files from a computer t...
  • How to Cross-Compile libiconv for Android
    If your legacy C/C++ code includes <iconv.h> to convert the encoding of characters from one coded character set to another, and you ne...
  • Configuring the Apple Airport Extreme with Verizon FIOS
    I have Verizon FIOS triple-play service and I love the TV picture quality and internet speed and reliability, but I don't like Verizon...
  • Problems with new version of rpmbuild
    The Problem With the new version of rpmbuild installed on CentOS 6.x, if you try to use an old RPM spec file, you will get an error like the...
  • Once upon a time there were Bell Labs...
    Today is another step closer to the end of an era for the old AT&T Bell Labs (now called AT&T Labs). Our estimated colleague David K...
  • Installing the Android NDK
    These instructions refer to a Ubuntu 12.04.1 LTS system running on an Intel processor. Head to the  http://developer.android.com/tools/sdk/n...
  • How to cross-compile Python for Android
    When it comes to cross-compiling Python for Android, I've followed Gabriel's blog post @ http://mdqinc.com/blog/2011/09/cross-compil...
  • Upgrading mid-2007 24in iMac with an SSD and a 2.5in HDD in the optical bay
    I own a mid-2007 24in iMac with a 2.4 GHz Intel Core 2 Duo processor, 4GB of DDR2 DRAM, running Mac OS Mountain Lion, and for the past few m...

Categories

  • Android
  • Apple
  • Arduino
  • ARM
  • busybox
  • CentOS
  • DHCP
  • Fortran
  • GNU
  • GPON
  • iMac
  • Javascript
  • ksh
  • Linux
  • MacOSX
  • Mips
  • Network
  • Python
  • Router
  • UNIX
  • Windows
  • x86

Blog Archive

  • ▼  2013 (12)
    • ▼  October (1)
      • Once upon a time there were Bell Labs...
    • ►  August (1)
    • ►  May (1)
    • ►  February (3)
    • ►  January (6)
  • ►  2012 (11)
    • ►  December (2)
    • ►  November (2)
    • ►  October (7)
Powered by Blogger.

About Me

Unknown
View my complete profile