Sunday, May 18, 2014

Android Kernel Compile | Galaxy Fit S5670 | ARM Basics

Very recently I was asked by one of my professors to compile a custom kernel to his phone. He gave me an old Samsung Galaxy Fit phone.  This post documents the process carried out to do the same.

The phone runs ARMv6-compatible processor rev 5 (v6l) and supports features like



swp [SWaP] & swpb [SWaPByte]

This instruction is deprecated as of ARMv7 even in some later versions of ARMv6

This instruction was used to implement exclusive access to semaphores themselves.
Semaphores are used to manage access to a shared resource. Depending on the type of semaphore, one or more clients may be granted access.
Before accessing a resource, a client must read the semaphore value and check that it indicates whether the client can proceed, or whether it must wait. When the client is about to proceed it must change the semaphore value to inform other clients.
A fundamental issue with semaphores is that they themselves are shared resources, which – as we just learned – must be protected by semaphores.
SWP (Swap) and SWPB (Swap Byte) provide a method for software synchronization that does not require disabling interrupts. This is achieved by performing a special type of memory access, reading a value into a processor register and writing a value to a memory location as an atomic operation. The example code below shows the implementation of simple mutex functions using the SWPinstruction. SWP and SWPB are not supported in the Thumb instruction set, so the example must be assembled for ARM.
binary mutex functions
    EXPORT lock_mutex_swp
lock_mutex_swp PROC
    LDR r2, =locked
    SWP r1, r2, [r0]       ; Swap R2 with location [R0], [R0] value placed in R1
    CMP r1, r2             ; Check if memory value was ‘locked’
    BEQ lock_mutex_swp     ; If so, retry immediately
    BX  lr                 ; If not, lock successful, return
    ENDP

    EXPORT unlock_mutex_swp
unlock_mutex_swp
    LDR r1, =unlocked
    STR r1, [r0]           ; Write value ‘unlocked’ to location [R0]
    BX  lr
    ENDP
In the SWP instruction in above example, R1 is the destination register that receives the value from the memory location, and R2 is the source register that is written to the memory location. You can use the same register for destination and source. For example 
        SWP r2, r2, [r0]       ; Swap R2 with location [R0], [R0] value placed in R2
is a valid instruction.

But there are certain limitations to this. If an interrupt triggers while a swap operation is taking place, the processor must complete both the load and the store part of the instruction before taking the interrupt, increasing interrupt latency. Because Load-Exclusive and Store-Exclusive are separate instructions, this effect is reduced when using the new synchronization primitives. In our source for Galaxy Fit we will find that swp or swpb aren't used to create atomic operations but Load-Exclusive and Store-Exclusive. Here is an example 

static inline void atomic_add(int i, atomic_t *v)
{
unsigned long tmp;
int result;

__asm__ __volatile__("@ atomic_add\n"
"1: ldrex %0, [%3]\n"
" add %0, %0, %4\n"
" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");

}

This is taken from atomic.h of /arch/arm/include/asm/ directory.
In a multi-core system, preventing access to main memory for all processors for the duration of a swap instruction can reduce overall system performance. This is especially true in a multi-core system where processors operate at different frequencies but share the same main memory.

half [Half - Precision Floating Point Support]

In the ARM's VFP [Vector Floating Point Co-Processor] the support for 'half' means that it supports 16 bit floating point numbers and conversions between 16-32 bit floating point numbers. Half-precision floating-point numbers are provided as an optional extension to the VFPv3 architecture.
Half-precision floating-point format

Where:
   S (bit[15]):      Sign bit
   E (bits[14:10]):  Biased exponent
   T (bits[9:0]):    Mantissa.
The meanings of these fields depend on the format that is selected.

thumb [The Thumb Instruction set]

The Thumb instruction set is a subset of the most commonly used 32-bit ARM instructions. Thumb instructions are each 16 bits long, and have a corresponding 32-bit ARM instruction that has the same effect on the processor model. Thumb instructions operate with the standard ARM register configuration, allowing excellent interoperability between ARM and Thumb states.
On execution, 16-bit Thumb instructions are transparently decompressed to full 32-bit ARM instructions in real time, without performance loss.
Thumb has all the advantages of a 32-bit core:
  • 32-bit address space
  • 32-bit registers
  • 32-bit shifter, and Arithmetic Logic Unit (ALU)
  • 32-bit memory transfer.
Thumb therefore offers a long branch range, powerful arithmetic operations, and a large address space.
Thumb code is typically 65% of the size of ARM code, and provides 160% of the performance of ARM code when running from a 16-bit memory system.
The availability of both 16-bit Thumb and 32-bit ARM instruction sets gives designers the flexibility to emphasize performance or code size on a subroutine level, according to the requirements of their applications. For example, critical loops for applications such as fast interrupts and DSP algorithms can be coded using the full ARM instruction set then linked with Thumb code

fastmult [Fast Multiplication]

This refers to the fact that the processor can do 32 bit multiplication. The processor implementing this provides hardware to preform 32bit x 32 bit = 64 bit operation. This is a common feature in almost all the processors nowadays. But still they guys who built the kernel felt the need to mention it.

vfp [Vector Floating Point Co-Processor]

The VFP coprocessor supports floating point arithmetic operations and is a functional block within.
The VFP has its own bank of 32 registers for single-precision operands that you can:
  • use in pairs for double-precision operands
  • operate loads and stores of VFP registers in parallel with arithmetic operations.
The VFP supports a wide range of single and double precision operations, including ABS, NEG, COPY, MUL, MAC, DIV, and SQRT. The VFP effectively executes most of these in a single cycle. Sometime in future I promise to do a tutorial on this and NEON instructions.

edsp [DSP extensions]

The ARM DSP instruction set extensions increase the DSP processing capability of ARM solutions in high-performance applications, while offering the low power consumption required by portable, battery-powered devices. DSP extensions are optimized for a broad range of software applications including servo motor control, Voice over IP (VOIP) and video & audio codecs, where the extensions increase the DSP performance to enable efficient processing of the required tasks.

Features

  • Single-cycle 16x16 and 32x16 MAC implementations
  • 2-3 x DSP performance improvement over ARM7™ processor-based CPU products
  • Zero overhead saturation extension support
  • New instructions to load and store pairs of registers, with enhanced addressing modes
  • New CLZ instruction improves normalization in arithmetic operations and improves divide performance
  • Full support in the ARMv5TE, ARMv6 and ARMv7 architectures

Applications

  • Audio encode/decode (MP3: AAC, WMA)
  • Servo motor control (HDD/DVD)
  • MPEG4 decode
  • Voice and handwriting recognition
  • Embedded control
  • Bit exact algorithms (GSM-AMR)

java [Jazelle]

Jazelle DBX (Direct Bytecode eXecution) allows some ARM processors to execute Java bytecode in hardware as a third execution state alongside the existing ARM and Thumb modes. Jazelle functionality was specified in the ARMv5TEJ architecture and the first processor with Jazelle technology was the ARM926EJ-S. Jazelle is denoted by a 'J' appended to the CPU name, except for post-v5 cores where it is required (albeit only in trivial form) for architecture conformance.
These are the extra features that the processor supports over the regular ones. The kernel can only be complied over linux or Mac. For this one I will be using linux. First we need to install a few requirements and then download the source.


You will find the following files in the kernel source. Next install the required programs to compile the source. Run the following line in your terminal.

sudo apt-get install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev valgrind
Extract the kernel source. And also download the toolchain. Now extract the toolchain. and place it in a folder. You'll find the following in the toolchain folder.

Go to the kernel source and edit the Makefile to add the CROSS_COMPILE to point to the toolchain. It must look like this


Make sure the path is right. For me the toolchain was in /home/regnarts/S3/arm-2011.03 check the full path before updating.

Now to make this kernel there is a small problem. The original kernel source that was released by the samsung didn't have any support for Ext filesystem. That was because the original rom for this phone runs on samsung's proprietary RFS file system. So if you want to only run the stock rom over the kernel then just jump this part. Else you will need to enable the support for this in the config file. Find /arch/arm/configs/beni_rev01_defconfig and change the File System settings as shown below.


There is another important thing. The phone uses proprietary wifi/wireless drivers. So their source code is not provided. Therefore we need to just use the already existing ones. But the problem is that insmod checks for the kernel version before loading the modules. So if there is a mismatch. The kernel won't load the modules. Therefore you'll need to name the kernel as the module wishes to see it. Run

make menuconfig

This opens up the menu to configure the kernel.

In general setup append the name "-pref-CL928291" to the Local version. Now you are good to go. Run the make script that came with the kernel make_kernel_GT-S5670.sh. Or run

make beni_rev01_defconfig
make

That should give us the kernel. You will find it as /arch/arm/boot/zImage. Congratulations you've built the kernel for your phone. However you will need to still put it up in to the phone. For this we shall make the android's very popular "recovery flashable" zip file.

Download a sample file. Extract the zip, you'll find this

Now the file boot.img is the kernel+ramdisk file. But in order to build a boot.img you'll first need a ramdisk. We shall take the ramdisk from the sample previously downloaded. Use boot-tools to unpack and use the boot.img. The following must help
To unpack the boot.img

tools/unpackbootimg -i source_img/boot.img -o unpack

To unpack ramdisk (If you want to)

gzip -dc ../unpack/boot.img-ramdisk.gz | cpio -i

Replace boot.img-zImage with your own zImage and then run

tools/mkbootimg --kernel unpack/boot.img-zImage --ramdisk unpack/boot.img-ramdisk-new.gz -o target_img/boot.img --base `cat unpack/boot.img-base`

With the new boot.img replace it in the update.zip and zip it again.
This will flash in most of the recoveries if you turn of the signature verification. If you are unable to do it in your recovery. Then you'll need to sign it. Use this to sign it from linux.

export CLASSPATH=$CLASSPATH:./lib.jar
java testsign update.zip update-finished.zip

Now flash the zip file from recovery.
I'll discuss overclocking this phone in the next blog post.






Thursday, May 15, 2014

Serial Communicaion Level Converters | RPi / BeagleBoard to Arduino / ATMegaX | UART

Working on my college project I came across the problem of interfacing a custom designed control board based on ATMega8 microcontroller to RPi that would run the main program. UART seemed to be the best option. The problem is that RPi runs its UART at 3.3V level and BeagleBoard runs its at 1.8V level and ATMegaX runs its UART at 5V level. Therefore there was a need for converter. Here are the schematics and design of the one that I built.
It is simply two transistor based inverters shifting the logic up and resistor network putting the logic down. The resistor logic is to step down the voltage for RPi. If you intend to use this for BeagleBoard then please change the resistances to appropriate values. You can download the PCB file and pdf.

Note:
We need to replace the lines  
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
with
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
in /boot/cmdline.txt
and comment out the line
#Spawn a getty on Raspberry Pi serial line 
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
to get
#Spawn a getty on Raspberry Pi serial line 
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
in /etc/inittab
In Raspberry Pi if you wish to use the port for other uses than the terminal access.
In BeagleBoard you will need to setup the pins to work as serial. Please refer to the relevant documentation
Use software like minicom to access the ports.


Sunday, December 8, 2013

FFMPEG on Android | Command line tool

Got the ffmpeg command line tool working on android today. I was working on a screenshot binary for android. And the way you take a screenshot on android is to cat /dev/graphics/fb0. Now this file is in RGB565 format [on Emulator]. Initially I managed it by pulling the file to my computer and then using ffmpeg to convert it to jpg. Though porting ffmpeg for android was not my initial idea, and it has already been done before. But I didn't find any ffmpeg binaries online that I could directly download and run over my phone. Therefore I decided to see if I could build it from source and it took me a couple of hours to get it working. The binary runs all the user commands except the common options like "-h","-v" [For some reason there was no definitions to cover those in the source I used]. You can download the binaries here [Need to copy the library 'libffmpeg.so' to the '/system/lib' folder]. I did, even copy the binary to my 'system/bin' so that I can comfortably run it from the shell.
To finish of the work I wrote a shell script to do rest of the work

#Shell script to take a screenshot
cat /dev/graphics/fb0 > /sdcard/raw-input
ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 480x800 -i /sdcard/raw-input -f image2 -vcodec mjpeg /sdcard/screenshot.jpg

rm /sdcard/raw-input
echo "Screen shot saved at scard/screenshot.jpg"


I do know that there is an inbuilt screenshot binary in android that does the work instead of this lousy process. But I am working on something more interesting. To be revealed in the days to come.

Have fun with ffmpeg

Here are some screenshots that were pulled from the device
PS: I am not sure if it works on all versions of android. I've only tried it on KitKat...

Thursday, November 21, 2013

Audio Amplifier | TDA2050

A quick update on the audio amplifiers. This is a higher power IC, TDA2050. The data sheet claims that it can do up to 32W. I simply put up a application circuit from the datasheet. I put it into a temporary PCB layout that I designed. I've plans to design a complete 5.1 channel amp, more updates on it later. The circuit produces awesome amount of sound, enough for your neighbors to complain. And I was only running a small speaker that I had designed.




Here is a video of it working, [My room's a mess :(]


Check the same on youtube for better quality


I'll update with the circuit layout very soon

Tuesday, October 15, 2013

OpenSLES | Android audio interface through c

Open SL | ES (Open Sound Library for Embedded Systems) is a software library created by khronos group. It is a royalty free, cross platform, hardware accelerated c - language 2D and 3D audio API. This has been adopted as the standard in android since API level 9 [gingerbread]. It follows the object and interface model. Rest of this post details creating a simple c program to play sound.

I will be using the 8bit pcm file that came with android ndk as my sound source.  We can play other popular streams too, but for this article the program will just say 'hello android'. The api calls for an 'engine' object to be created at first. This diagram illustrates the required relationship

Before we start anything let's include the necessary headers


#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>


The pcm 8 bit values to say hello are encoded in the file hello_clip.h [found it one of the examples in android ndk]. The values look like this.

"\x01\x00\x03\x00\x06\x00\x0a\x00\x0a\x00\x09\x00\x04\x00\x04\x00"
"\x06\x00\x06\x00\x00\x00\xff\xff\x05\x00\x08\x00\x01\x00\xfe\xff"
"\xff\xff\x03\x00\x04\x00\xfe\xff\xf9\xff\xfd\xff\x04\x00\xfe\xff"
"\x03\x00\x04\x00\x01\x00\xfb\xff\xfb\xff\xfc\xff\xfb\xff\x03\x00"
"\xfc\xff\xf9\xff\xfc\xff\x01\x00\x06\x00\x00\x00\xf9\xff\xfa\xff"
"\x04\x00\x06\x00\xfe\xff\xfa\xff\xfd\xff\x01\x00\xfe\xff\xfe\xff"
"\xfe\xff\xfd\xff\xfd\xff\xfd\xff\xfe\xff\xff\xff\xfd\xff\xfa\xff"
"\xfe\xff\x00\x00\x03\x00\xfe\xff\xfc\xff\xfb\xff\xfe\xff\x01\x00"
        .............................................................

So lets create an object of engine and realize it. Don't worry its not that complicated stuff. assert() is used to check if everything is all right on creation of engine and its realisation. 

     SLresult result;

     static SLObjectItf engineObject = NULL;
     
     //First we need to create an engine and then check if it was successful
     result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
     assert(SL_RESULT_SUCCESS == result);
     
     //We realize the engine object
     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
     assert(SL_RESULT_SUCCESS == result);

Now we get the engine interface [observe that we need two things to control the engine ObjectItf and EngineItf].

     static SLEngineItf engineEngine;
     
     //Get the engine's interface
     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
     assert(SL_RESULT_SUCCESS == result);

Now we create the output mix

     static SLObjectItf outputMixObject = NULL;

     const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
     const SLboolean req[1] = {SL_BOOLEAN_FALSE};
     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
     assert(SL_RESULT_SUCCESS == result);

Observe that output mix is used to control the quality of the output. It maintains the equalisation, virtualiser, etc,. The ids and req help the function in determining the type of the output mix. Here we tell the function that we don't want the environmental reverberation settings. We also need to realise this 

     // realize the output mix
     result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
     assert(SL_RESULT_SUCCESS == result);

Next we create a buffer queue, set data type  and configure the source.

     // configure audio source
     SLDataLocator_AndroidSimpleBufferQueue loc_bufq =   {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
     SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8,
         SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
         SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
     SLDataSource audioSrc = {&loc_bufq, &format_pcm};

Next create an audio sink

     SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
     SLDataSink audioSnk = {&loc_outmix, NULL};

Now its the time we can create our audio player. We mention that Buffer queue, Effect send and volume objects are required 

     const SLInterfaceID ids2[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND,
         SL_IID_VOLUME};
     const SLboolean req2[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
         SL_BOOLEAN_TRUE};
     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
                                                 3, ids2, req2);
     assert(SL_RESULT_SUCCESS == result);

We need to realise this too.

     result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
     assert(SL_RESULT_SUCCESS == result);

Now we need to the player interface and the buffer queue interface

     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
     assert(SL_RESULT_SUCCESS == result);
     
     // get the buffer queue interface
     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
                                              &bqPlayerBufferQueue);
     assert(SL_RESULT_SUCCESS == result);

At the end of each frame next frame has to be loaded. There is a call back functionality available. This function is implemented and linked to the main program. Let us create a function first.

void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
    assert(bq == bqPlayerBufferQueue);
    assert(NULL == context);
        if (NULL != nextBuffer && 0 != nextSize) {
        SLresult result;
        result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
        assert(SL_RESULT_SUCCESS == result);
        nextBuffer = NULL;
        nextSize = NULL;

    }
}

We will use this to play a second frame and then stop. The second frame will be saying 'android'. It was taken from the same example. We shall register this callback 

     result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
     assert(SL_RESULT_SUCCESS == result);


Then we set the player state to playing

     result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
     assert(SL_RESULT_SUCCESS == result);

Now we put the buffers out to play

     nextBuffer = (short *) hello;
     nextSize = sizeof(hello);
     result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
     assert(SL_RESULT_SUCCESS != result);
     nextBuffer = (short *) android;
     nextSize = sizeof(android);

     sleep(2);

This will play hello first and then call the call back function, which will play android as it is queued next. There is a delay to complete the playing.

     if (bqPlayerObject != NULL) {
         (*bqPlayerObject)->Destroy(bqPlayerObject);
         bqPlayerObject = NULL;
         bqPlayerPlay = NULL;
         bqPlayerBufferQueue = NULL;
     }
     

     if (outputMixObject != NULL) {
         (*outputMixObject)->Destroy(outputMixObject);
         outputMixObject = NULL;
         outputMixEnvironmentalReverb = NULL;
     }
     
     if (engineObject != NULL) {
         (*engineObject)->Destroy(engineObject);
         engineObject = NULL;
         engineEngine = NULL;
     }

We destroy all the objects created, and then exit the program.

Download the binaries and code from here. You will have to run it through either adb or terminal emulator by copying the binaries to convenient place, like /data/local/tmp. Try it out, let me know if the code or binary doesn't work. Should work flawlessly on a jelly bean device. Haven't checked it on any others



Tuesday, November 20, 2012

Java Calculator

Hi all!
         This is my first time posting to the REGNARTS blog.
So, this post as is rightfully titled, explains java applet through a simple calculator program which takes in 2 numbers, adds, subtracts, multiplies and divides them. Also it checks for possible errors in the input of the 2 numbers and displays the error if any.

PRE-REQUISITES: A little java education along with the concept of classes and a little experience with the eclipse java ide. For those who want to download the eclipse ide, the link's here.

Now lets look at the program,


If you see the first few lines before the commented boundary in green, they are called packages. Packages are collections of  related classes and interfaces(You'll learn about interfaces in an another post maybe. :P ) eg) to develop windows programs, applets, networking etc. The Java API consists of many such packages. Here "awt" means Abstract Window Tools, "applet" includes all those methods (btw functions in java are called methods) which are required to run this Applet, and "awt.event" controls any action performed within the applet window.

Now after the green commented boundary you'll see a line "public class AplNum extends Applet implements ActionListener". Here public class means objects of this class can be created in different files that are in the same folder as this file. If you are using some other editor then its important to name the file same as the name of the public class in the file in the file. Same reason you can have only one public class in one java file. Now the name of a class has to start with a capital letter as per proper java standards. It extends Applet implies it inherits properties and elements from the class Applet. The term applet is used for small java apps that are usually used for web designing. And finally it implements ActionListener implies the Applet runs the methods in ActionListener interface, that is used to detect any action happening inside the applet window. It contains one method which we are supposed to redefine in our code called as the "actionPerformed". Again first letter of any method is small case as per java standards!

Now inside the class we declare the members of the class, that is labels, buttons and textfields. Where label is used to display a msg, button used to click on something, and textfield is used to input and output data. Notice that all label elements have their names prefixed with 'l', buttons with 'b' and textfields with 't'. That is good program organisation for you!
now we discuss the init() function which is used to create the Applet. In this function you initialise the various members you have already created. first you use GridLayout to brand a layout to the applet. GridLayout gives a table like layout. Here it gives 8 row, 2 column table, with 15 pixel horizontal spacing and 10 pixel vertical spacing between the members. setSize is used to set the size of the applet window. The members are then added in order to the table. For a label, we initialise it to a default text supplied in "" inside the brackets. Textfields are initialised to size of text allowed in the textfield. And if that textfield is not used for inputting then we need to disallow editing using setEditable(false). And buttons are initialised to default display text. addActionListener(this) implies action performed on those members are detected by the actionListener interface. Finally add() is used to add the member to the respective record in the layout. Like this all members of the class are intitialised.

Now lets check the next function used to input numbers and check for errors!
Try catching is an error handling mechanism in java. Here if any error occurs in java, that catch statement is executed that has the erroneous object as its parameter. getNos() function returns true if the inputs are correct and returns false if inputs are wrong. Here flag is set to false meaning default assumption is that the input is erroneous. Then inside try{} we use getText() of textfield to get any string entered in that textfield. Then we use Integer.parseInt() to convert the string into number. If the string doesnt just contain numbers then it throws an error. All errors belong to the Exception class. This error is caught and respective steps are taken to handle it. In this case, we set the format using different functions and display the error msg in tmsg and clear up the tnum1 and tnum2 for further input.If all the numbers are entered correctly then tmsg is cleared.

Now that we have safely input the numbers, lets look at the actionPerformed function that I previously said we need to redefine to suit our code.
First it checks for the integrity of the input numbers given. Then it displays the respective results. If you click the add button, the actionListener gets activated and it raises the actionPerformed function and if the source of the action is the add Button, the sum will be displayed and an "Addition successfull" msg is shown. Same thing goes for subtract, multiply and divide with respective solutions and msges. But for division it also checks for divide by zero error!

Now that you've written the project, compile and run it in eclipse and you will get the following applet window:
I've already performed the operations so you'll see all the textfields are full!
Now for those who want to run the applet though command prompt and you already have jdk installed in your system and your classpaths set up you can first create the following html file named AplNum.html:
then run the command: javac AplNum.java to compile the file and give the class file. then run the command: AppletViewer AplNum.html in your command window and poof! you'll get the same applet window!
I seriously hope you people try it out, and please comment you're reviews about the post and the program!
Also, I have a question for you, Which editor have I used to code the above program? Answer to win a chance to acquire some guaranteed goodies! :)
I thank Regnarts for allowing me to post on his blog.
Dude, you are not always awesome but then that's the beauty of it! ;)
Yours,
anty_kryst
Follow me at twitter "@anty_kryst" or on facebook "antykrissh".
Bye!

Friday, October 19, 2012

Audio Amplifier | LM386

I managed to create a basic audio amplifier using the IC LM386. This post is just a walk through to the creation. LM386 is a very good audio amp, but sometimes it tends to oscillate at low frequencies hence producing a lot of unwanted noise. The basic circuit is

Put this on a bread board. And connect a 3.5mm jack to the other end to input Vin. Use a coupling capacitor of possibly 10uF. The 10K Pot is to control the intensity. Use Vcc of around 9V. I've used a 8ohm speaker.





There is one more mode according to the datasheet. This is supposed to provide a gain of 200.



Sometimes when the gain is more the output is distorted. Be sure to keep that in mind. It is not that powerful. I've always had a hard time handling it, lot of distortions and noise. Check out other modes, experiment, enjoy.