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
Thursday, 14 May 2015
controlling VFD with arduino...
i made a simple code to control VFD (change the speed and direction of ac drive) with arduino.
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
/*
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/
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
output
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
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
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
simple code to demonstarte this conversion is
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
and the result is

code to convert int to hex and store to the string with 4 bytes representation is
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
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)
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

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)
Thursday, 7 May 2015
converting int values into HEX and storing it in a Array
the function utoa() is used to do the all work for you.
ex:
ex:
Subscribe to:
Posts (Atom)