Wednesday, June 15, 2016

Controlling MeArm Robot arm from an android device

I recently bought a MeArm robot arm and assembled.


This consists of 4 servo motors to control base, shoulder, elbow and gripper. Later I found "MeArm Controller" android application and decided to configure arduino bluetooth module to complete my setup.

Following is the breadboard view of my configuration.


I found it bit hard to configure the android app for the first time hence decided to note down configuration steps below.

1. Turn bluetooth on and open the application.






















2. Press the settings icon (triangle just below Reset button). This should take you to the following screen.




















3. Press the Connectivity button.




















4. Then tap on the bluetooth icon and select the correct address.
Now you should get a screen saying connected :)























5. Select the slider mode then provide Servo IDs.




















6. Press OK and you should get a screen similar to the following, where you have controls to the 4 servo motors.




















Here is my messy robot arm config,


Arduino sketch: (Credit to the original creator- I have only  modified baudrate for the bluetooth module)


#include <SoftwareSerial.h>
#include <Servo.h>
Servo base; //Create an object servo base
Servo shoulder; //Create an object servo shoulder
Servo elbow; //Create an object servo elbow
Servo gripper; //Create an object servo gripper
char ServoID; //Variable for Servo ID
int hasilButton; //Variable button pressed results
int nilaiBase; //Variable servo base value
int nilaiShoulder; //Variable servo Shoulder value
int nilaiElbow; //Variable servo Elbow value
int nilaiGripper; //Variable servo Gripper value
const int increment = 5; //Increase degree (B+, S+, E+, G+)
const int decrement = 5; //Decrease degree (B-, S-, E-, G-)
String readString; //Read string values
SoftwareSerial BT(12,13); //Bluetooth RX TX on pins 12 and 13
void setup() {
Serial.begin(9600); //Set the Serial Baudrate 9600
BT.begin(9600); //Set Baudrate Bluetooth accordance with your bluetooth module
pinMode(13,OUTPUT); //Set pin 13 as output
base.attach(6); //Set the servo base of the pin 6
shoulder.attach(9); //Set the servo shoulder of the pin 9
elbow.attach(11); //Set the servo elbow of the pin 11
gripper.attach(10);
//Set the servo gripper of the pin 10
base.write(90); //Start positioning servo base to 90 degrees
shoulder.write(90); //Start positioning servo shoulder to 90 degrees
elbow.write(90); //Start positioning servo elbow to 90 degrees
gripper.write(90); //Start positioning servo gripper to 90 degrees
}
void loop() {
if (BT.available()) { //If bluetooth available
Serial.println("BT available");
hasilButton = BT.read(); //Set hasilButton = Bluetooth Read
Serial.println("BT hasilButton " + hasilButton);
ServoID = BT.read(); //Set ServoID = Bluetooth Read
Serial.println("BT ServoID " + ServoID);
base.write(nilaiBase); //Set the degree of servo according nilaiBase
shoulder.write(nilaiShoulder); //Set the degree of servo according nilaiShoulder
elbow.write(nilaiElbow); //Set the degree of servo according nilaiElbow
gripper.write(nilaiGripper); //Set the degree of servo according nilaiGripped
if(hasilButton == 'X'){ //If the button = X (X can customize the application MeArm Controller)
digitalWrite(13, LOW); //Turn off the led on pin 13
}
if(hasilButton == 'Z'){ //If the button = Z (Z can customize the application MeArm Controller)
digitalWrite(13, HIGH); //Turn on the led on pin 13
}
if(hasilButton == 'a'){ //If the button = a (a can customize the application MeArm Controller)
nilaiBase-=decrement; //Servo base value - value decrement
}
else if(hasilButton == 'A'){ //If the button = A (A can customize the application MeArm Controller)
nilaiBase+=increment; //Servo base value + value increment
}
if(hasilButton == 's'){ //If the button = s (s can customize the application MeArm Controller)
nilaiShoulder-=decrement; //Servo base shoulder - value decrement
}
else if(hasilButton == 'S'){ //If the button = S (S can customize the application MeArm Controller)
nilaiShoulder+=increment; //Servo shoulder value + value increment
}
if(hasilButton == 'e'){ //If the button = e (e can customize the application MeArm Controller)
nilaiElbow-=decrement; //Servo base elbow - value decrement
}
else if(hasilButton == 'E'){ //If the button = E (E can customize the application MeArm Controller)
nilaiElbow+=increment; //Servo shoulder value + value increment
}
if(hasilButton == 'g'){ //If the button = g (g can customize the application MeArm Controller)
nilaiGripper-=decrement; //Servo base gripper - value decrement
}
else if(hasilButton == 'G'){ //If the button = G (G can customize the application MeArm Controller)
nilaiGripper+=increment; //Servo gripper value + value increment
}
if(ServoID=='1'){ //If ServoID = 1
baseServo_slider(); //Call subroutine baseServo_slider
}
if(ServoID=='2'){ //If ServoID = 2
shoulderServo_slider(); //Call subroutine shoulderServo_slider
}
if(ServoID=='3'){ //If ServoID = 3
elbowServo_slider(); //Call subroutine elbowServo_slider
}
if(ServoID=='4'){ //If ServoID = 4
gripperServo_slider(); //Call subroutine gripperServo_slider
}
}
}
void baseServo_slider(){
delayMicroseconds(300);
while (BT.available()) {
char c = BT.read();
readString += c;
}
if (readString.length() >0) {
Serial.print("Base : ");
Serial.println(readString.toInt());
nilaiBase = (readString.toInt()); //nilaiBase = readString from android
base.write(readString.toInt()); //Set the degree of servo base according to the value ReadString
readString="";
}
}
void shoulderServo_slider(){
delayMicroseconds(300);
while (BT.available()) {
char c = BT.read();
readString += c;
}
if (readString.length() >0) {
Serial.print("Shoulder : ");
Serial.println(readString.toInt());
nilaiShoulder = (readString.toInt()); //nilaiShoulder = readString from android
shoulder.write(readString.toInt()); //Set the degree of servo shoulder according to the value ReadString
readString="";
}
}
void elbowServo_slider(){
delayMicroseconds(300);
while (BT.available()) {
char c = BT.read();
readString += c;
}
if (readString.length() >0) {
Serial.print("Elbow : ");
Serial.println(readString.toInt());
nilaiElbow = (readString.toInt()); //nilaiElbow = readString from android
elbow.write(readString.toInt()); //Set the degree of servo elbow according to the value ReadString
readString="";
}
}
void gripperServo_slider(){
delayMicroseconds(300);
while (BT.available()) {
char c = BT.read();
readString += c;
}
if (readString.length() >0) {
Serial.print("Gripper : ");
Serial.println(readString.toInt());
nilaiGripper = (readString.toInt()); //nilaiGripper = readString from android
gripper.write(readString.toInt()); //Set the degree of servo gripper according to the value ReadString
readString="";
}
}
view raw MeArm - BT hosted with ❤ by GitHub

Wednesday, June 8, 2016

Measure performance of a given JavaScript code

console.time("for loop");
for(var i=0; i < 100; i++){
  console.log("i is: " + i);
}
console.timeEnd("for loop");

Wednesday, April 27, 2016

How to add git branch name to the command line

How many times you run the git branch command to find out which branch you in?

Following will help you to overcome above hassle and have a quick glance at your branch name.



1. Open /home/<USER>/.bashrc file.
2. Add following to the bashrc, save and exit.
parse_git_branch() {
 git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
 PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\]\$ '
else
 PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
3. Open a new terminal window and browse your git repo :)

Friday, April 22, 2016

First shot with the AF_Motor Library

I had to use an Arduino motor shield as a HAT on a uno board, powered by four 1.2V rechargeable batteries, to power-up two DC motors. ( Yes, juice provided by arduino is not enough to power two motors )

 
























Since this is my first library usage, I had to find out how to install a library in my workspace and decided to note the steps as a reference here.

Howto Install the Library-

1. Download the library, in my case AF_Motor from
https://github.com/adafruit/Adafruit-Motor-Shield-library/zipball/master.

2. Unzip and rename to motorsheild and copy in to the sketchbook libraries directory. (Create libaries directory, if not exists)
Eg:- /home/udara/sketchbook/libraries/ directory.

Why Rename: Default library name(adafruit-Adafruit-Motor-Shield-library-89a0973), contains hyphen(-) characters which causes library pickup issue during IDE startup.



3. Start/Restart IDE.

Hint: Browse File> Examples, you should see motorsheild sample sketches.

Sunday, April 3, 2016

how to resolve "M: bad interpreter" while working with bash scripts

This is a common problem if you try to port a script created in windows environment to unix,
 /bin/bash^M: bad interpreter: No such file or directory
How to solve this,

run dos2unix <BASH_SCRIPT>
Eg:- dos2unix run.sh

For further information: http://www.linuxcommand.org/man_pages/dos2unix1.html

Wednesday, March 2, 2016

Getting HTTP response back from a CURL POST request

CURL request:
curl -H "Content-Type: application/json" -H "Authorization: Basic <AUTH_VALUE>" -X POST -d '<BODY_CONTENT>' <EP_URL> -k -i

Sample request:

curl -H "Content-Type: application/json" -H "Authorization: Basic YWRtaW46YWRtaW" -X POST -d 'MBfcEW/91R0VTobzhbC0ZGjGvHN4c9OXFsbByP8s9IwJErS5FVAgOhzxAJCLh3tfl0MJad5joQ7X5jl7mAzy40Rjv6Pe4wVghjVjdmofYL/fuX8m/pToUmvWc9t7S4DER31lGPBrlWEpEtIk/Nj025Xm5/cvAsUXpuTvLeOYt5v+cYHHmNtulG1dEfzMYQbjTQ1W/TVvWHG8LUfdXvVXt0R3QI6r/DnVszVIOKDbpD7OdKkLQ9J7W4kOSDZL1euIaSaWfLr0l+K0M+Eme1jG9np/qmNXOGZZyXR+ETpGuPDASV3TVK9hXKH18COwQ//e0db+6bGSPLPIb1KcshKIz4xZ3z15OaXDHRzZx71gFO4raVYIQAbxlx0wSw/D2Ap1qkXvBYFGIqAW+NPzVCGu/8Vu9BaUcSBZ5v1v4RKstWHKmaRTlRpRs0i1uEBoZHuw3sCN+HWLeIIjjNcWpNs3L1E1H/Wzny3uxwiPqZolA4LsnRj8kY5yJ1FoqNFs+i2lPqUvLhQZMCvPCF+onIQd1DImgK/VZSgDXNxRpo0N+6ZJEBMLAVWRSCHtHO28DLSBKjeacELa6jfzLEEE2cJIbTyjrGsQ+YTEHgL8zuQNIZZD5yO0bO4DU3eSGN66r4snnL+YC7r8cBfl8DQCBaWLNfs18eYtaOxwOJnqcZYI/8sWk8bFNDGgNn3imE3U1RpJrNZA68d53owzE0PQvZKkJIdR+Oy2W0wGcpjVOXj3HXLTXmjR9y/R/eZZ2nzvrPjwnnBGRYcX0pwenH+PSv+KSrilr6Z3cYWMlC8SUXDaHsXG6Pk3lxZX1sHziX0Sdgwb+KBtqpm5amU6rdBfSDmHO+Km3wxehlDh8Nv2BpwxWm1QGaXD1UXRyWLb5PgHPXPv21tG+kvhjoSYSUuXyMecnd8pwbjE1jRublcOvoMiXCLSd7lA9cg5TSTU0KgkR7N0E0Bt+znbpITiNqpmOhA9bjMwQyr5J6tzO8CjLL992Hn6WUe7mxu6Va9bv0kww6xyBSPdOXOfyDz/CxDZLtUsnmi2Fi70tmSAz690jzgaoupH8X2O7JhzRX7v+EMow5xqXPZ3i3d2FcvBjssmFPZh10Y13+sSTRWn3ciYcfx2c+/a00c+bxMSFg0FWEtcpptY0tQkJhrGn+f49ARDk2wZoYEBLkE/KKnpvk1p6HFFwkJsHdslrtV5QDjzRVPGx5rIrt1Sp3qhOFAYHnAoxF6XcgTLx8+q2tUlft+XdTy61zo/So1/+n6VxawCwZIkn5UHzAfAL2BaYA4OaqMnTY97s6ILCip4e5+/CKzT7LbL14cAjVs6fI4lZ/9nsuSgpTPBqzhvSzKRx3Pjg4TllcjaFyq0/f6MAEnSSz2Ir2tL5ue0fLI29YSLDfa6+R2t0fKvqkklg3/KhMs4vWlr/g2oFVyCtZWIWXXtnzN/z8g86H9UJv5FAg0x2/p/TXF87g+gYLgMGDAGuMWCHH2D789EXrdOq/hNnFDqoYoO9OzqnFWktO3Hjg7cqGUEVHlIwNuDxabzeGsj5zW+72F8gODWFKV1O10I+zEmA4RMdXkBlUz515jt/w/Q/Sb8SazMqEgzhL4LPsV6bFX9pSN8nb9PiI/6sXq2sTGIdN/czqrRE7j/xBywhvcZXA9g+8yiUnZKwJ5YQkoAIKCySh0auw19/GqaU4bwt3TPBuomW3UTdHE=' https://localhost:9443/endpoints/PageLogEventReceiver -k -i

Sample response: 

HTTP/1.1 401 Unauthorized
Set-Cookie: JSESSIONID=B083D193C0722F2CA8021BA2021BA4F0; Path=/; Secure; HttpOnly
Content-Type: text/html;charset=UTF-8
Content-Length: 14
Date: Wed, 02 Mar 2016 16:30:48 GMT
Connection: close
Server: WSO2 Carbon Server

_AUTH_FAILURE_

Friday, February 19, 2016

WSO2 ESB Mutual SSL - Certificate exchange

We need to consider two scenarios here.

1. External system act as a client to ESB. 
     Eg:- SOAP UI invoking ESB proxy

2. External system is a server to ESB.
    EG:- ESB invoking external service

Following image depicts all certificate exchange steps to cater above scenarios.



Wednesday, February 17, 2016

how to import a private key in to JKS

Lets take following scenario where you implement an application based on asymmetric cipher (Eg:- RSA). Assume you are responsible for the decryption part, where you have to use the given private key to handle this.




Probably you will get only the private key or private key and the certificate. I'm going to take the first instance assuming you have only the private key.

Note :- assume name of the private key is private_key.pem

1. Create a certificate sign request using the given private key.
openssl req -new -key private_key.pem -out key_cert_r.csr
2. Get the certificate signed by an authorized party/self-sign.
Self-sign:
openssl x509 -req -days 365 -in key_cert_r.csr -signkey private_key.pem -out key_cert.crt
3. Generate a pkc12 key store using the private key and above certificate.
openssl pkcs12 -export -name alias -in key_cert.crt -inkey private_key.pem -out keystore.p12
4. Generate a java key-store using above pkc12 keystore.
keytool -importkeystore -destkeystore tmp_keystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias alias

If you already have java key store configured within your application, let's merge above tmp_keystore.jks with the existing key store.
keytool -importkeystore -destkeystore existing_keystore.jks -srckeystore tmp_keystore.jks

Sunday, February 7, 2016

SVN cheat sheet

This is not the place to learn SVN commands, I'm just creating this as a  reference to some important commands.

Revert local file change

svn revert <file_name>

Take a diff from two revisions

svn diff -r <old_revision>:<new_revision>

Update to the latest revision

svn update "<path>"

Update to a specific revision

svn update -<revision_number> "<path>"

Add new files/directory to track

svn add <file_name>|<directory_name>

Delete with a message

svn -m "<messahe>" delete "<path>"

Saturday, January 30, 2016

Build Carbon Application(capp) for WSO2 DAS

You need to work with multiple artifact types while working with WSO2 DAS. Following is a list of artifacts supported in WSO2 DAS, (Tried both DAS 3.0.0 and 3.0.1)


  • Event Streams
  • Event Stores
  • Even Receivers
  • Analytic Scripts
  • Execution Plans
  • Gadgets
  • Layouts
  • Dashboards


Rather than deploying these artifacts one by one we can deploy a set of artifacts using a single deployable artifact, Carbon Application (capp)[1]. Here what we do is, create an archive with .car extension and deploy using management console.


But there can be usecases where we need to build above archive programmatically, using a build tool. Here I’m using Maven to fulfil above requirement.


Assume we have all artifacts within das-capp directory,


.
├── das-capp
│   ├── artifacts.xml
│   ├── Dashboard_1.0.0
│   ├── Eventreceiver_1.0.0
│   ├── Eventstore_1.0.0
│   ├── Eventstream_1.0.0
│   ├── GadgetTotalDailyViews_1.0.0
│   ├── GadgetViewsPreviousmonth_1.0.0
│   ├── GagdetPageFilter_1.0.0
│   ├── Layout_1.0.0
│   └── Sparkscripts_1.0.0
└── pom.xml

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.wso2.das.example</groupId>
 <artifactId>das-capp</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>DAS CAR</name>
 <description>This project contains artifacts to process and display sample capp</description>
 <properties>
    <artifact.types>jaggery/app=zip,service/rule=aar,lib/library/bundle=jar,event/receiver=xml,synapse/message-processors=xml,synapse/endpointTemplate=xml,synapse/message-store=xml,synapse/proxy-service=xml,event/execution-plan=siddhiql,carbon/application=car,registry/resource=zip,lib/dataservice/validator=jar,synapse/endpoint=xml,web/application=war,synapse/inbound-endpoint=xml,synapse/sequence=xml,synapse/configuration=xml,lib/registry/handlers=jar,synapse/task=xml,service/meta=xml,webapp/jaxws=war,synapse/api=xml,synapse/lib=zip,bpel/workflow=zip,lib/registry/filter=jar,service/dataservice=dbs,event/publisher=xml,synapse/local-entry=xml,synapse/priority-executor=xml,synapse/event-source=xml,synapse/template=xml,event/stream=json,lib/carbon/ui=jar,service/axis2=aar,synapse/sequenceTemplate=xml,wso2/gadget=dar,lib/synapse/mediator=jar</artifact.types>
 </properties>
 <build>
    <pluginManagement>
     <plugins>
       <plugin>
         <artifactId>maven-antrun-plugin</artifactId>
         <version>1.7</version>
       </plugin>
     </plugins>
    </pluginManagement>
    <plugins>
     <plugin>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
         <execution>
           <phase>process-resources</phase>
           <goals>
             <goal>run</goal>
           </goals>
           <configuration>
             <tasks>
               <zip destfile="target/das-example.car">
                 <zipfileset dir="das-capp" />
               </zip>
             </tasks>
           </configuration>
         </execution>
       </executions>
     </plugin>
    </plugins>
 </build>
</project>


You can build above using mvn clean install and find the capp artifact within target/ directory. Then we can upload this deployable artifact to WSO2 DAS using management console.


[1] https://docs.wso2.com/display/DAS301/Packaging+Artifacts+as+a+C-App+Archive

Thursday, January 28, 2016

Configure WSO2 server to start automatically after reboot

I have tested following within a RHEL box, but with a slight modification to the run-level, same script can be used within other Linux distros.

Assume we have WSO2 DAS server within /carbon/wso2/das directory and JDK installed in /carbon/java/ directory. Make sure to update these two according to your environment.

 1. Copy following startup-script to the /etc/init.d directory.
 2. Execute chmod a+x and a+r on the script.
 3. Set run level using "sudo chkconfig dasserver on"
 4. Recheck above using "chkconfig --list dasserver" This should output ,
 "dasserver       0:off   1:off   2:on    3:on    4:on    5:on    6:off"
Startup script
#! /bin/sh
#
# dasserver          Start up the WSO2 DAS server
#
# chkconfig: 2345 55 25
# description: WSO2 Data Analytics Server is a comprehensive enterprise data analytics platform.

export JAVA_HOME="/carbon/java/jdk1.8.0_65"


startcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh start > /dev/null &'
restartcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh restart > /dev/null &'
stopcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh stop > /dev/null &'

case "$1" in
start)
   echo "Starting the WSO2 DAS Server ..."
   su -c "${startcmd}" wso2usr
;;
restart)
   echo "Re-starting the WSO2 DAS Server ..."
   su -c "${restartcmd}" wso2usr
;;
stop)
   echo "Stopping the WSO2 DAS Server ..."
   su -c "${stopcmd}" wso2usr
;;
*)
   echo "Usage: $0 {start|stop|restart}"
exit 1
esac