Tuesday, 19 May 2015

Using relay with Arduino

references :

http://www.electronics-tutorials.ws/io/io_5.html

http://www.electroschematics.com/8512/microcontroller-relay-interface-and-driver/

https://electrosome.com/interfacing-relay-8051-keil-c/

Thursday, 14 May 2015

VFD & arduino

references :

https://deltautomation.wordpress.com/2011/04/29/plc-vfd-comunication/

http://fightpc.blogspot.in/2014/10/vfd-control-with-arduino-using-rs485.html

http://www.avrfreaks.net/forum/vfd-microcontroller

controlling VFD with arduino...

i made a simple code to control VFD (change the speed and direction of ac drive) with arduino.

/*
Author : Kunchala Anil [anilkunchalaece@gmail.com]

Interfacing VFD with Arduino Via RS485 using MODBUS Protocol
MODBUS protocol
-------------------------------------------------------------------------
| Start Bit | Address | Function_Command | DATA | LRC or CRC | Stop bit |
| : | 2bytes | 2 bytes | | 2 bytes | \r\n |
-------------------------------------------------------------------------

Function Code : The format of data characters depend on function codes
The available function codes are described as follows:
0x03 : Read data from register
0x06 : Write single data to register
0x10 : Write multiple data to registers

MODBUS Protocol can be implemented in two ways ASCII or RTU(Remote Terminal Unit)
iam gonna use ASCII mode for this example

____________________________________________________________________________
| Content Address Functions
|-------------------------------------------------------------------------
| B1 B0
| 0 0 --> NO function
| Bit 0 - 1 0 1 --> Stop
| 1 0 --> Run
| 0x2000 1 1 --> Jog + Run
|
| Bit 2 - 3 Reserved
|
| B5 B4
| 0 0 --> No function
| Command Bit 4 - 5 0 1 --> FWD
| Read / Write 1 0 --> REV
| 1 1 --> Change Direction
|
| Bit 6 - 15 Reserved
|
| 0x2001 Frequency Command
|
|__________________________________________________________________________________


Command Address B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 Hex Equalent
RUN 0x2000 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0x0012
STOP 0x2000 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0x0011
Format if data send to the VFD
':' --> Start bit in Ascii mode
\r\n --> Stop bit


*/

//commands values
#define VFD_START 1
#define VFD_STOP 2
#define VFD_SPEED 3

#define MAX_SIZE 20 // max size of data buffer

char speed_vfd[] = ":01062001";
const char start_vfd[] = ":010620000012C7\r\n";
const char stop_vfd[] = ":010620000011C8\r\n";
char data_buffer[MAX_SIZE];

void setup(){
Serial.begin(9600);
}//end of setup


void loop(){

serial_ask(); /* ask question the user to enter
1 to start the VFD
2 to stop the VFD
3 to set the speed of VFD */
int val = serial_check(); /* wait for user to enter the data and convert
it to Int and return value into function */
perform_action(val); /* perform the action based on the user entered value
which is passed to the function */

}//end of loop


/*
SERIAL_ASK() FUNCTION : this function is used to ask the user to enter the user choice via Serial monitor
*/
void serial_ask(){
Serial.println("Please Enter all values followed by \n");
Serial.println("Please enter the valid code to perform");
Serial.println("-------------------");
Serial.println("CODE\t ACTION");
Serial.print(VFD_START);Serial.println("\t START VFD");
Serial.print(VFD_STOP);Serial.println("\t STOP VFD");
Serial.print(VFD_SPEED);Serial.println("\t SET SPEED");
Serial.println("-------------------");
}//end of serial_ask() fucntion


/*
SERIAL_CHECK() FUNCTION : this function is used to receive the data into data_buffer
*/
int serial_check(){
while(!data_received())
{
//wait until full data is received
}//end of while
return atoi(data_buffer);
}//end of serial_check() function


boolean data_received(){
static byte index = 0;
while(!Serial.available())
{
//wait until user enter the data
}

if(Serial.available())
{
char input = Serial.read();
if(input !='\r')
{
data_buffer[index] = input;
index = index + 1;
}else
{
data_buffer[index] = 0;//null terminate the character array to make it string
index = 0;
return true;// we received the full code return true
}//end of ifelse condition
}
return false;
}//end of data_received()) function

void perform_action(int val){
switch(val)
{
case VFD_START:
Serial.println("VFD START");
VFD_control(start_vfd);
break;

case VFD_STOP:
Serial.println("VFD STOP");
VFD_control(stop_vfd);
break;

case VFD_SPEED:
Serial.println("SET SPEED");
set_speed();
break;

default:
error_message();

}//end of switch
}//end of perform action

void VFD_control(const char* command){
Serial.print(command);
Serial.println();
}

void set_speed(){
char freq_hex[4];//temporary string for sprintf
Serial.println("Set Speed");
Serial.println("enter the frequency");
int freq = serial_check();
Serial.print("the frequency you entered is");
Serial.println(freq);
sprintf(freq_hex,"%04X",freq);//convert it to hex using sprintf
strcat(speed_vfd,freq_hex);
cal_LRC();

}//end of set_speed() fucntion

void cal_LRC(){
int val = calculate(); //function to calculate the decimal value
convert_to_hex(val);// function to convert the decimal value to HEX
}//end of cal_LRC() fucntion


//CALCULATE() FUNCTION
int calculate(){
int val[strlen(speed_vfd)/2]; // val[] array is used to store the decimal value for two HEX digits
for (int i = 1, j = 0 ; i < strlen(speed_vfd); i = i+2, j++ ) //i = i+2 because we are finding the decimal equalent for two HEX values
{
val[j] = conv(speed_vfd[i],speed_vfd[i+1]); // function to convert Two Hex numbers into Decimal Value

}//end of for loop

int sum = find_sum(val); // function to calculate total sum of decimal equalents
return sum;
}//end of calculate() function

//FUNCTION_SUM() FUNCTION
int find_sum(const int * val) // we are passing an array to the function
{
int sum = 0;
for(int i=0;i<= (strlen(speed_vfd)/2) - 1;i++)
{
sum = sum + val[i];
}//end of for loop
return sum;
}//end of find_sum() function

//FUNCTION TO CONVERT HEX TO THE DECIMAL VALUE
int conv(char val1,char val2){
int val_a = toDec(val1); // convert to the decimal value
int val_b = toDec(val2);
return (val_a*16) + val_b; // converting decimal value into HEX decimal Equalent B1*16 + B0
}//end of conv() function

int toDec(char val){
if(val<='9')
{
return val - '0'; // please see the ASCII table for clarification
}
else
{
return val - '0'-7; // 7 is offset for capital letters please see the ASCII table
}

}//end of toDec() function

void convert_to_hex(int val){
char hex[5];
utoa((unsigned)val,hex,16); // utoa() function is used to convert unsigned int to HEX array (whatever the base we specified as third argument)

int hex_val = (int)strtol(hex,NULL,16);// strtol() is used to covert string into long int according to the given base

hex_val = ((~hex_val) + B01) & 0xff; /* finding the 2's complement of the number hex_val
'~' operator is the logical not and adding B01 to it and logical anding with 0xff
to omit any excess bites otherthan 8 bits or 1 byte
*/
Serial.print("the LRC value is : ");
Serial.println(hex_val,HEX);
char hex_val_str[4];
sprintf(hex_val_str,"%0.2X",hex_val);// putting hex value in the string back
Serial.print("the concated string is : ");
strcat(speed_vfd,hex_val_str);
char ter[] = "\r\n";
strcat(speed_vfd,ter);//adding terminators at the end STOP bits
Serial.println(speed_vfd);
}//end of convert_to_hex() fucntion


void error_message(){
Serial.println("You Entered Wrong Command");

}//end of error_message()

it actually doesn't do anything.. we can modify the code to send the modbus control to the VFD.
I don't have the hardware to test it But i made the code using VFD-m Manual
delta VFD-m

Arduino & load cell

references :

http://flowrc.co.uk/load_cell_stage_3.html

http://dailylearningnotes.blogspot.in/2010/03/working-with-load-cell-2.html

http://christian.liljedahl.dk/guides/arduino-and-load-cell


http://www.mechtechplace.net/mech-tech-electronics/building-a-low-cost-strain-gage-load-cell-amplifier/

Friday, 8 May 2015

Finding a Two's complement of a number


void setup(){
int a= 10;
int val = b;
Serial.begin(9600);
a = ~a ; //inverting the number
a = a+B01 ;//addinf the 1 to it
a = a & 0xff;//anding with 0xff to avoid any bit overflow
Serial.print("the 2's complement of ");
Serial.print(val,BIN);
Serial.print("is : ");
Serial.println(a,BIN);
}

void loop(){
}

LRC calculation for MODBUS ASCII Protocol In Arduino

In MODBUS Ascii mode each 8 bit data is the combination of two ascii characters
for ex: a 1 byte data 64H is shown as '64' in ASCII, consist of '6'(36 Hex) and '4'(34 Hex) (i still need to figure out the difference between those and standard ASCII values)

to calculate LRC for frame ":010304010001"
we need to add 01H + 03H + 04H + 01H + 00H + 01H = 0aH,
the 2's complement negation of 0aH is f6H

code to perform this is

/*
Author : Kunchala Anil
Calculating the LRC of HEXA numbers used in MODBUS ASCII

In MODBUS ASCII protocol : is used as starting word
The special function used in this code is utoa() and strlen() and sprintf()

utoa() --> unsigned integer to String for base conversion

syntax : utoa((unsigned int)val , string , base)

where val : is the value to be converted into base N format
string : is the temporary string to store the converted value
base : base is the Radix which val is converted (in this code it is 16)

strtol() --> string to long int

syntax : strtol(str,end_ptr,radix)
str : string to be converted
end_ptr : end pointer (NULL)
base : radix of the system

sprintf() --> string print function

syntax : sprintf(str,format)
str : destination string where output is stored

*/
char a[] = ":010304010001"; // ASCII string lrc being added

void setup(){
Serial.begin(9600); // start the serial communication
Serial.print("The string to which LRC is calculated is : ");
Serial.println(a);
int val = calculate(); //function to calculate the decimal value
convert_to_hex(val);// function to convert the decimal value to HEX
}//end of setup()

void loop(){
//do nothing here
}//end of loop()

//CALCULATE() FUNCTION
int calculate(){
int val[strlen(a)/2]; // val[] array is used to store the decimal value for two HEX digits
for (int i = 1, j = 0 ; i < strlen(a); i = i+2, j++ ) //i = i+2 because we are finding the decimal equalent for two HEX values
{
val[j] = conv(a[i],a[i+1]); // function to convert Two Hex numbers into Decimal Value

}//end of for loop

int sum = find_sum(val); // function to calculate total sum of decimal equalents
return sum;
}//end of calculate() function

//FUNCTION_SUM() FUNCTION
int find_sum(const int * val) // we are passing an array to the function
{
int sum = 0;
for(int i=0;i<= (strlen(a)/2) - 1;i++)
{
sum = sum + val[i];
}//end of for loop
return sum;
}//end of find_sum() function

//FUNCTION TO CONVERT HEX TO THE DECIMAL VALUE
int conv(char val1,char val2){
int val_a = toDec(val1); // convert to the decimal value
int val_b = toDec(val2);
return (val_a*16) + val_b; // converting decimal value into HEX decimal Equalent B1*16 + B0
}//end of conv() function

int toDec(char val){
if(val<='9')
{
return val - '0'; // please see the ASCII table for clarification
}
else
{
return val - '0'-7; // 7 is offset for capital letters please see the ASCII table
}

}//end of toDec() function

void convert_to_hex(int val){
char hex[5];
utoa((unsigned)val,hex,16); // utoa() function is used to convert unsigned int to HEX array (whatever the base we specified as third argument)
int hex_val = (int)strtol(hex,NULL,16);// strtol() is used to covert string into long int according to the given base
hex_val = ((~hex_val) + B01) & 0xff; /* finding the 2's complement of the number hex_val
'~' operator is the logical not and adding B01 to it and logical anding with 0xff
to omit any excess bites otherthan 8 bits or 1 byte
*/
Serial.print("the LRC value is : ");
Serial.println(hex_val,HEX);
char hex_val_str[4];
sprintf(hex_val_str,"%0.2x",hex_val);// putting hex value in the string back
Serial.print("the concated string is : ");
strcat(a,hex_val_str);
char ter[] = "\r\n";
strcat(a,ter);//adding terminators at the end or STOP bits
Serial.println(a);
}//end of convert_to_hex() fucntion


output
LRC_output

Playing with Strings, HEX and Integer values.

In the past few days I have tough time converting Inter values into Hex values and how to store them in strings.
If once i stored them How to get their Hex representation Back..

first of all.. Int is a Data type where HEX is a Data representation
so if i wanted to convert Int To HEX and send the value through Serial Hardware
i can do something like this

int val = 100;
void setup(){
Serial.begin(9600);
Serial.print(val);
}
void loop(){
}


output:
3e8

ok HEX representation of 1000 is 3e8 and it is converted and send through serial hardware.
But what if we wanted to store that Equivalent Hex value into some variable or assign that value to another variable?

So we need a way to store that converted Hex value. but to which data type we need to store the HEX value?
like i said before HEX is not a datatype it is a data representation. even though it is holding a integer value we cannot assign it to the int datatype because of characters A to Z.

One possible solution is using strings.so we need to perform the conversion and store that value in string

hopefully there is a function call that will do the work for us it isutoa()
utoa --> unsigned int to String Base conversion
syntax : utoa((unsigned int) val,string,base)
where val is the val converted to Hex format
string is char string which holds output after conversion
base is radix for conversion 0,8,16

utoa()

Convert an unsigned integer into a string, using a given base

Synopsis:
#include

char* utoa( unsigned int value,
char* buffer,
int radix );
Arguments:
value
The value to convert into a string.
buffer
A buffer in which the function stores the string. The size of the buffer must be at least:
8 × sizeof( int ) + 1

bytes when converting values in base 2 (binary).

radix
The base to use when converting the number.



simple code to demonstarte this conversion is

int val = 1000;

void setup(){
char str[4];
utoa((unsigned int) val,str,16);
Serial.print("the val is : ");
Serial.println(val);
Serial.print("the HEX converted string is : ");
Serial.println(str);
}

void loop(){
}


output:
the val is : 1000
the HEX converted string is : 3e8

we commonly use 2 bytes or 4 bytes as HEX representation.. so if we wanted to represent 1000 in HEX 4 byte format we write something like 03e8. we add zero before MSB to make it 4 bytes But Arduino doesn't it do that automatically for us. so we somehow has to tell Arduino that we need to print fixed bytes representation because this will cause major problem if we wanted to send the hex value in the middle of string.

this is done using sprintf() function
sprinf() : string print function which is used to store the string in specified format

which dones same duty as printf but rather than printing to standard io it format the data and store it in string

syntax:sprintf(str,format,arguments)
where str is the string where formatted data is stored
format is used to specify the format
arguments is the arguments supplied to arguments

Here format is the key thing that do the job
that can be explained using the following c program

#include
int main() {
int data = 29;
printf("%x\n", data); // just print data
printf("%0x\n", data); // just print data ('0' on its own has no effect)
printf("%8x\n", data); // print in 8 width and pad with blank spaces
printf("%0.8x\n", data); // print in 8 width and pad with 0's
getch();

return 0;
}


and the result is
sprintf format

code to convert int to hex and store to the string with 4 bytes representation is

int a = 1000;
void setup(){
Serial.begin(9600);
char str[4];
sprintf(str,"%0.4x",a);
Serial.print("the HEX converted string is : ");
Serial.println("str");
}

void loop(){
}


those are used when we wanted to use functions like strcat() to concate strings

But what if we have a HEX string and wanted to get the int value back from the string. in this case atoi() won't help us because it only convert integer string not HEX string

in this code strtol() will be useful.
strtol --> string into long integer
convert a string into long integer according to the given Base.

syntax: strtol(str,end_ptr,base)
str : string which converted
end_ptr: end pointer
base : radix of values stored in string
it returns the long int value we need to cast to int if wanted to assign it to int variable
The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes as many characters as possible that are valid following a syntax that depends on the base parameter, and interprets them as a numerical value. Finally, a pointer to the first character following the integer representation in str is stored in the object pointed by endptr.


char str[] = "03e8";
void setup(){
Serial.begin(9600);
int val = (int)strtol(str,NULL,16);
Serial.println(val);
}
void loop(){
}


Output:
1000

the functions do our bidding is:
utoa -- unsigned int to ascii string with base
utoa(int val, char* str, radix)

strtol -- string to long int
strtol(str,end_ptr,radix)

sprintf -- string printf
sprintf(string,format)