Monday, November 30, 2009

Mapping MobileMe iDisk in Windows

I have a mobile Me account, which is integrated with my IPhone. The subscription comes with a 20GB space for storage. However, I rarely use it to upload photos..etc, and the space is pretty much a waste.

So, I started exploring ways by which I could use that space as an online storage of my files (Something like Drop Box, but have much more space)

The following steps details how to map a network drive in windows 7 to the iDisk folder:

  1. Open windows explorer, and go to Tools—> Map Network Drives…If the “Tools” menu is not visible, try pressing the “ALT” key
  2. In the network drive mapping dialog, enter the folder path as : http://idisk.me.com/<username>, where, <username> is your signin userid which you use at http://www.me.com image
  3. Check the “Connect Using Different Credentials” checkmark
  4. Click on “finish”, and enter your mobileme credentials when asked. Thats it!!!

Enjoy putting your iDisk in Mobile Me account, to use.

Thursday, August 13, 2009

Finding BADI in any SAP transaction

One of the options to consider when a need arise to change the standard out of the box SAP feature is to take advantage of Business Add ins , or in short, BADIs. BADIs are basically exit classes which are integrated in the SAP transaction program, and are called during execution, usually with run time variables which can be modified. By taking advantage of these BADIs, application developers can change these variables during run time, based on the business rules, and transfer the values back to the main SAP transaction application, there by modifying the way in which standard out of the box SAP transaction work.

The 2 transactions of notice when coming to BADIs are SE18 and SE19, where we implement the BADIs using our own classes. These classes use the same interface as that of the BADI class.

Having said that, many a times, the issue I have run into, especially in a new environment is how to find these exit points/BADIs that are available for a given transaction. One option is to spend a very long time debugging and keeping a close eye on each and every call that is made in the SAP program. However, this is not an option when it comes to web transactions because web applications time out.

The BADI class we implement is considered an Instance of the actual BADI class. For SAP to find out if a BADI has any active implementations, it first calls a static method called “getInstance()” of class : CL_EXITHANDLER. If we set a break point within this method, the execution will break for every single BADI that is implemented in the SAP transaction.

Hence, set a Break point in: CL_EXITHANDLER=>GET_INSTANCE()

While this is a sure shot way of finding BADIs in a transaction, the down part of this method is that there will be too many break point hits. The most effective method to find BADIs is to go to SDN and check out the user forums. However, if all else fails, the method I detailed below will get you the BADI you are looking for.

Tuesday, February 17, 2009

Controlling Servo Motor Positions using Duration in Parallax Basic Stamp BS2

 

One of the problems I came across when attempting to control a servo motor was the position of motor horn. It is a well known fact that the servo motor need pulses for it to work. This is achieved by raising voltage on control pins (Hi), Making it Low (LO), and then, pausing for set amount of time, say , 20 ms. The “Raising” and Making “Low” can be achieved using the PULSOUT command. The syntax of PULSOUT command is as follows:

PULSOUT <pinNumber>, <Duration>

The Pin number is an obvious parameter (Doh!), but the Duration part is a bit tricky, because the unit of Duration is actually 2 micro Seconds (written as 2us from now on).

Hence, the following command:

                    PULSOUT 14, 1

Will result in getting a pulse to pin 14, with HIGH lasting for just 2us, and then becoming LOW. Lets see another example:

                    PULSOUT 14,1000

will result in getting a pulse to pin 14 with HIGH lasting for 1000*2us  = 2ms. The relevance of this duration discussion will become evident in just a second. Basically, it is this duration, that determines the positioning of a servo motor horn / amount of turn that the motor will do when its given control pulse. This pulse train needs to be sent to servo motor once in say 10 – 30 ms. Hence, to hold a motor on a particular location, we use FOR loops and PAUSE statements, as you will see in the example shortly.

For now, here is a diagram which gives an idea of durations and locations. This diagram was got from Parallax forums, where one of the best teacher, Andy Lindsay posted the information.

Servo Position Control WRT a Clock's Hour Hand

As you can see from the above diagram, to achieve a horn position of 12:00 O Clock, the following can be used, assuming the control pin is PIN 14:

PULSOUT 14, 750

Similarly a 9 O’Clock position –> PULSOUT 14, 1250

3 O’Clock Position –> PULSOUT 14, 250

As we can see, as the duration becomes higher than 750, the movement becomes counter clockwise. With duration lesser than 750 (which = 750* 2us = 1.5 ms ), the motor turns clockwise.

Now, with that “mystery” duration out of our way, lets see an example which will turn the servo motor Counter Clockwise, Clockwise, and then, to 12 O’Clock position. This is the program I came across when starting my robotics/electronics/microcontroller studies, and got utterly confused on how/why the servo motor was behaving as it was. The following program was available in the Microcontroller tutorial book by Parallax, written by Andy Lindsay. After the book was published, with many people having the same question, Andy Lindsay published an extra page on this topic in Parallax forum site. The following URL will take you there:

http://forums.parallax.com/forums/default.aspx?f=6&m=164400

Now, to the program:

********************************* Begining of program *******************

  counter VAR Word

DEBUG "counterclockwise 10 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 1000
   PAUSE 20
NEXT

DEBUG "clockwise 2 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 500
   PAUSE 20
NEXT

DEBUG "center 12 oclock", CR

FOR counter = 1 TO 150
  PULSOUT 14, 750
   PAUSE 20
NEXT

DEBUG "all done"

END

*********************************End Of Program *************************

The First Loop

DEBUG "counterclockwise 10 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 1000
   PAUSE 20
NEXT

First, the servo motor will get 150 pulse signal trains, each HI lasting for 1000 * 2us = 2ms duration. After each such signal, the PAUSE 20 will insert a delay of 20 milliseconds, and the loop continues. As per our discussion earlier, regarding the duration and location of servo motor horn, we understand that the servo horn should come somewhere near 10 O’Clock position. Once it reaches the position, the motor will hold that position for some time. Now, how much time does it hold that position? Lets find out…

Each loop has a pause of 20 ms. Also, each pulse last 2 ms. Hence, total delay in the loop = 20 ms (from PAUSE) + 2 ms (from duration of PULSOUT) = 22ms.

Hence, total time required to execute the first 150 loops
                                       = 22 * 150
                                       = 3300 milliseconds
                                       = 3.3 Seconds.

The Second Loop

DEBUG "clockwise 2 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 500
   PAUSE 20
NEXT

Now, lets consider the second loop. Here too, the servo motor will get a train of 150 pulses. But this time, the duration parameter is 500. This means that each pulse will last only 500 * 2us = 1ms.

From what we have seen in above duration/position explanation/diagram, we understand that the servo motor will move to a location somewhere near to 2 O’Clock position, and hold the position. Again… for how long? Lets find out:

Each loop as a pause of 20ms, because of the PAUSE command. Also, each pulse last 1 ms.

Total delay of loop = 20 ms (From PAUSE) + 1ms (from PULSOUT)
                            = 21 ms.

Total time required to execute 150 loops
                            =  21ms * 150
                            = 3150 milliseconds
                            = 3.1 Seconds.

I leave it to you to figure out how the 3rd and final loop works.

Food For Thought

Before concluding this post, let me discuss how to control the time for which the servo motor holds a position. Remember.. in real world though… we may be using an infinite loop to get input from say, a switch/sensor, to control the motor. But for this example, we can control the time and speed in which the motor moves by changing the number of loops and the PAUSE parameter. In the first loop, increasing the PAUSE duration will result in the servo motor getting to the intended position more slowly, and then holding the position.

However, if you want to motor to reach its position fast, and THEN hold the position, leave the PAUSE duration alone, but increase the number of loops. Think about it … :).

Thursday, January 22, 2009

Visual C# Ternary operation

Right from my days of C++, this ternary operation has always confused me, primarily because I never spent enough time to understand this operation. Now that I have, I am documenting it here so that this can be referred back in future if needed, or for others like me.

The only ternary operation in C# is the comparison operation which has the following syntax:

<test>?<resultIfTrue> : <resultIfFalse>

Example:

string resultString = (myInt<10) ? "Yep!!!!" : "Nope!!!"

Here, the resultString variable will hold the string "Yep" if the variable myInt has a value less than 10. Otherwise, if the value held by myInt is greater than or equal to 10, the variable resultString will hold a value "Nope!!!".

Tuesday, January 06, 2009

Useful SAP Business Object Type programming macros.

 

Figuring out the Key to instantiate an Object

Go to SWO1 transaction and display the object type you want to instantiate. Now, at the top, click on the "Program" button, as shown in the figure.

1-6-2009 2-36-18 PM

You will notice that there is a section starting with "BEGIN OF KEY" and ending with "END OF KEY". This is your key declaration. You will want to create a type of the same structure in your ABAP application, before you can instantiate the object type in your application.

Instantiating a Business Object

To instantiate a business object, first create a Type/structure using aforementioned technique. For the above object, the type declaration will be as shown:

REPORT  zgn_object_create.

DATA: BEGIN OF objkey,
    airline LIKE sflight-carrid,
    connectionnumber LIKE sflight-connid,
    flightdate LIKE sflight-fldate,
END OF objkey.

One More Step Before Using the Business Object Programming Macros

All the macros we are going to discuss here is defined in the include program "CNTN01". Hence, the first step before using any Business Object Programming macros would be to include CNTN01 object in the application like so:

REPORT  zgn_object_create.
INCLUDE <cntn01>.

DATA: BEGIN OF objkey,
    airline LIKE sflight-carrid,
    connectionnumber LIKE sflight-connid,
    flightdate LIKE sflight-fldate,
END OF objkey.

SWC_CREATE_OBJECT - Instantiate Object Reference.

The SWC_CREATE_OBJECT macro is used to instantiate a business object. The syntax is as follows:

SWC_CREATE_OBJECT <Object> <ObjectType> <ObjectKey>

All object references, irrespective of the actual object type, have the data type definition SWC_OBJECT.

For example, for instantiating a customer object, the following could be the code.

Data Customer TYPE SWC_OBJECT.
SWC_CREATE_OBJECT Customer 'KNA1' customerID.

SWC_GET_PROPERTY - Macro to get a single valued attribute

SWC_GET_PROPERTY macro can be used to access single valued attributes from object instance. Syntax is as follows:

SWC_GET_PROPERTY <Object> <Attribute> <AttributeValue>

When attempting to access attributes of the same object (say, when developing methods, you want to access the attributes of the object), we can use "self" as the object name. For example, to access an attribute "Name", the following can be used:

SWC_GET_PROPERTY self 'Name' namevalue.

 

SWC_GET_TABLE_PROPERTY - Macro to get multiple value attribute

SWC_GET_TABLE_PROPERTY macro can be used to access multiple valued attributes (Multi Line attributes). Syntax is as follows:

SWC_GET_TABLE_PROPERTY <Object> <Attribute> <Value>

For example, to get a list of all movies playing in a theatre, the following can be used:

SWC_GET_TABLE_PROPERTY Theatre 'MovieList' Itab_movies.

Where,

Theatre is the Object Instance

MovieList is the attribute name (Multi Line Attribute)

Itab_Movies is an internal table to hold the values of the multi line attributes.

 

SWC_SET_ELEMENT - Macro to set a single valued attribute

SWC_SET_ELEMENT macro can be used to set single valued attributes in an object instance. Please note that this macro can be used only within an object method. Syntax is as follows:

SWC_SET_ELEMENT CONTAINER <AttributeID> <Value>

Because there is no object reference in the syntax, it is obvious that the use of this macro is pretty much restricted to within a method in the object instance.  This in one way is a good thing, as this makes it impossible to modify the attribute values of a business object directly. If we have to modify the attribute value of a business object, we have to use the object methods, and use the set element macro inside that method.

SWC_SET_TABLE - Macro to set muti line attribute.

SWC_SET_TABLE macro can be used to set multi line attributes in an object instance. Please note that this macro can be used only within an object method. Syntax is as follows:

SWC_SET_TABLE CONTAINER <AttributeID> <Value>

As mentioned before, since this macro does not have an object instance reference, this macro can be used only inside an object method, adding a layer of control on changing attribute values of a business object instance.

 

EXIT_RETURN - Return exception information from a method.

When developing the business object methods, it is important that any problems that the method encounter be properly communicated back to the caller. This may not be a very strict requirement when making the method calls from ABAP programs. But, this is a big issue when making the method calls from work flows (Tasks). Raising an exception, and giving information back to the framework that something went wrong in method execution is the only way by which the workflow can take evasive/alternate paths to get the work done (Error Handlers). Since there is no saying where all the business object will be used (may be today, it would be used just in your program, but in future, someone may decide to use your object in a workflow), its always a good practice to raise appropriate errors from methods if something goes wrong. The syntax is as follows:

EXIT_RETURN <Exception> <Var1> <Var2> <Var3> <Var4>.

The EXIT_RETURN macro specifies the exception number and the parameters for the message. Messages can have a maximum of 4 parameters and all the parameters (Var1 tro var 4) are mandatory. So, what if I have only 1 parameter to send? Well, we just use "SPACE" in place of other parameters like so:

EXIT_RETURN <ExceptionID> <Var1> SPACE SPACE SPACE.