Showing posts with label Arduino Serial Communication. Show all posts
Showing posts with label Arduino Serial Communication. Show all posts

Saturday, 11 April 2015

Logical Operations

|| -- logical OR
&& -- logical AND
! -- logical NOT

logical AND

void setup(){
Serial.begin(9600);
Serial.println("checking the use of &&(logical AND) operator");
}

void loop(){
Serial.println("enter character or number");
while(!Serial.available()){
//wait until user enters the data
}//end of while

if(Serial.available()){
char ch = Serial.read();
Serial.println("the character");
if((ch = '0')){
Serial.println("you entered a number ");
Serial.print("the Number is \t");
Serial.print(ch - '0');
Serial.print("\n");
}else{
Serial.println("you entered character");
Serial.print("the chraracter you entered is\t");
Serial.print(ch);
Serial.println("");
}//end of If-Else condition
}//end of If condition
}//end of loop

Checking the Char is digit or not

The following program is used to check whether char is digit or not

void setup(){
Serial.begin(9600);
Serial.println("checking whether char is digit or not");
}

void loop(){
Serial.println("enter character or number");
while(!Serial.available()){
//wait until user enters the data
}//end of while

if(Serial.available()){
char ch = Serial.read();
Serial.println("the character");
if((ch = '0')){
Serial.println("you entered a number ");
Serial.print("the Number is \t");
Serial.print(ch - '0');
Serial.print("\n");
}else{
Serial.println("you entered character");
Serial.print("the character you entered is\t");
Serial.print(ch);
Serial.println("");
}//end of If-Else condition
}//end of If condition
}//end of loop


alternatively we can use isdigit() function from C reference.



isdigit
int isdigit ( int c );
Check if character is decimal digit
Checks whether c is a decimal digit character.

Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9

Parsing Commands


/*
Author : Kunchala Anil
*/
#define max_size 40
char data_buffer[max_size];
char data_cpy[max_size];
char data_cmd[max_size];
char data_val[max_size];
char question_1[] = "Please enter the command with value";
char cmd_1[] = "anil";
char cmd_2[] = "sunil";
char end_char = '@';
void setup(){
Serial.begin(9600);
Serial.println("\t\t Arduino Parsing commmands");
}//end of setup()

void loop(){
ask_question(question_1);
serial_check();
serial_output();
parse_commands();

}//end of loop()

void ask_question(char* question){
Serial.println(question);
}//end of ask_question() function

void serial_check(){
while(!Serial.available()){
//wait until user enters the data
}//end of while
while(!received()){
//loop until full data received
//Serial.println("received loop In serial_check() function");
}//end of while(received) function

}//end of serial_check() function

boolean received(){
static byte index = 0;
char input;
if(Serial.available()){
input = Serial.read();
if(input == '\r'){
data_buffer[index] = end_char;//Null terminating the string
data_buffer[index+1] = 0;//Null terminating the string
index = 0;//reset the index variable
return true;
}
else{
data_buffer[index] = input;
index = index + 1;
}//end of If-Else condition
}//end of IF condition
return false;
}//end of received() function

void serial_output(){
Serial.println("the data you enteres is");
Serial.println(data_buffer);
Serial.print("having a length of\t-->");
int length = strlen(data_buffer);
Serial.print(length);
Serial.print("\n");
Serial.print("\tindex \tchar\n");
for(int i=0;i<length;i++){
Serial.print("\t ");
Serial.print(i);
Serial.print("\t ");
Serial.print(data_buffer[i]);
Serial.print("\n");
}//end of for loop
}//end of serial_output() function


//FUNCTION TO PARSE COMMANDS
void parse_commands(){
byte index_cpy = 0;

int cmd_no = 0;

int length = strlen(data_buffer);
for(int i =0;i<length+1 ;i++){
if(data_buffer[i] == end_char){
cmd_no = cmd_no+1;
Serial.print("command no \t");
Serial.print(cmd_no);
Serial.print("\tis received\n");

parse_it(data_cpy);//call the function to find command and value
memset(data_cpy,0,strlen(data_cpy));
index_cpy = 0;
}else{
data_cpy[index_cpy] = data_buffer[i];
index_cpy = index_cpy + 1;
}//end of If Else condition
}//end of for loop

}//end of parse_commands() function

//FUNCTION TO SEPERATE COMMAND AND VALUE
void parse_it(char* data){
byte index_cmd = 0;
int length = strlen(data);
for(int i = 0; i < length+1; i++){
if(!isdigit(data[i])){
data_cmd[index_cmd] = data[i];
index_cmd = index_cmd + 1;
}else{
know_cmd(data_cmd,data);
memset(data_cmd,0,strlen(data_cmd));
memset(data,0,strlen(data));
break;
}//end of If Else condition
}//end of for loop
}//end of parse_it() function


void know_cmd( char* cmd,char* val){
if(strncmp(cmd,cmd_1,strlen(cmd_1)) == 0){
Serial.println("you received command for Anil");
float result = get_val(val);
Serial.print("The value for anil is\t");
Serial.print(result);
Serial.println("");
}else if(strncmp(cmd,cmd_2,strlen(cmd_2)) == 0){
Serial.println("you received command for Sunil");
get_val(val);
}else{
Serial.println("You received wrong command");
}//end of If Else-If condition
//memset(cmd,0,i);

}//end of know_cmd() fucntion

float get_val(char* val){
byte index_val = 0;
for(int j=0; j<strlen(val)+1; j++){
if(isdigit(val[j])){
data_val[index_val] = val[j];
index_val = index_val + 1;
}
}//end of for loop
Serial.println("the value of the command is");
Serial.println(data_val);
float return_val = atof(data_val);
memset(data_val,0,strlen(data_val));
return return_val;
}//end of get_val function

Thursday, 9 April 2015

Checking the char is digit or not ?


/*
Author : kunchala Anil
checking that if entered char is digit or not
*/
void setup(){
Serial.begin(9600);
}//end of setup()

void loop(){
Serial.println("enter char");
while(!Serial.available()){
//wait until user enters data
}
while (Serial.available()){
char ch = Serial.read();
Serial.print("the character you entered ");
if(isdigit(ch)){
Serial.print("is digit\n");
}else{
Serial.print("not digit\n");
}//end of If
}//end of while
}//end of loop

and the result is
isdigit

Note the Noline ending and baud rate at serial monitor

Tuesday, 7 April 2015

Simple Arduino Serial Monitor Calculator


/*
Author : Kunchala Anil
Arduino Calculator
This Program demonstrates the simple calculator using Arduino Serial Monitor
*/

#define max_data 20
char data_buffer[max_data];
boolean got_add = false,got_sub=false,got_mul=false,got_div=false;
float A,B;

void setup(){
Serial.begin(9600);
Serial.println("\t\t\t Arduino Calculator");

}//end of setup

void loop(){
ask_question_get_values();
ask_get_operator();
result();
}//end of loop

void ask_question_get_values(){
//get the value of A from user and display it
Serial.println("Enter the Value of A");
A = get_value();
Serial.print("the value of A you entered is\t");
Serial.print(A);
Serial.println("");

//get the value of B from user and display it
Serial.println("Enter the value of B");
B= get_value();
Serial.print("the value of B you entered is\t");
Serial.print(B);
Serial.println("");
}//end of ask_question_get_values() function



float get_value(){
static byte index = 0;
char input;
boolean read_data = false;
while(!Serial.available())
{
//wait until user enters data
}//end of while loop

input = Serial.read();
if(input !='\r'){
data_buffer[index] = input;
index = index++;
get_value();//loop until get the full word
}
else{
data_buffer[index] = 0;//terminate the char array with NULL to make it string
index = 0;
read_data = true;
}//end of if else condition

if(read_data){
float result = atof(data_buffer);//atof --> ascii to float
return result;
}//end of if condition

}//end of get_value() function

void ask_get_operator(){
Serial.println("please choose the computational operator");
Serial.println("\t addition \t\t--> a \n\t subtraction \t\t--> s\n\t multiplication \t-->m\n\t division\t\t-->d\n");
operator_check();
return;
}//end of ask_get_operator() function

void operator_check(){
char input;
static byte index;
boolean received = false;
while(!Serial.available())
{
//wait until user enters the data
}
input = Serial.read();
if(input != '\r'){
data_buffer[index] = input;
index = index + 1;
operator_check();//loop until receiving is completed
}
else{
data_buffer[index] = 0;//terminating with NULL
index = 0;
received = true;
}//end of if else condition

if(received == true){
received = false; // restore the previous value
if(strcmp(data_buffer,"a") == 0){
got_add = true;
Serial.println("you selected addition");
return;

}
else if(strcmp(data_buffer,"s") == 0){
got_sub = true;
Serial.println("you selected subtraction");
return;
}
else if(strcmp(data_buffer,"m") == 0){
got_mul = true;
Serial.println("you Selected Multiplication");
return;
}
else if(strcmp(data_buffer,"d") == 0){
got_div = true;
Serial.println("you Selected Division");
return;
}
else{
Serial.println("you entered a wrong character");
return;
}//end of if else-if else condition

}//end of If condition
}//end of operator_check() function

void result(){
float output;
if(got_add){
output = A+B;
got_add = false;
Serial.print("the result of addition is\t");
Serial.print(output);
Serial.println("");
}
else if(got_sub){
output = A-B;
got_sub = false;
Serial.print("the result of subtraction is\t");
Serial.print(output);
Serial.println("");
}
else if(got_mul){
output = A*B;
got_mul = false;
Serial.print("the result of multiplication is\t");
Serial.print(output);
Serial.println("");
}
else if(got_div){
output = A/B;
got_div = false;
Serial.print("the result of division is\t");
Serial.print(output);
Serial.println("");
}
else{
Serial.println("something went wrong");
}
}//end of result() function

Using Functions in Arduino

What is a Function ?
Function is a block of code that performs a specific task within a large program and relatively independent of the remaining code

what's the use of function ?
1.Functions make code more readable
2.we can reuse the code without rewriting it
3.easy to debug the code
4.function can be accessed from any location within a program and name of function is unique and global


How to Write a Function ?
The Syntax(technical name) of function is


returnType functionName(arguments)
{

functionBody;

return returnValue;
}



The arduino is based on c/c++ so a function declaration in arduino is same as C.

Before going to what is what in function syntax, let me remind you about function once agian.

function is a few lines of code with a separate name in a large / main program.

so we have to specify the name for the function

which is
functionName
in syntax

To do a Task we need specific information and that may/may not be coming from main program... But what if Our function needed information from main program?

so we need a way to pass information to the main program if needed

which is
arguments
in syntax and as stated before this is optional.

the few lines of code that performs specific task is called functionName

when we call function from main program, it must have a way to return the result of the task it performed to the main program or calling function.

returnType is used to specify the datatype of the function return variable
and
return returnValue; is used to return the actual value into calling function


But what if we don't want to return anything from the function.
void is used as returnType if function returns nothing.

structuring code into functional blocks is an good practice which is useful when we write the large code and it is easy to understand (if we given the specified functionNames)

Arduino Ex:

/*
Author : Kunchala Anil
Arduino code to describe the use of Functions
In this we ask the user to enter two Number and display it on serial monitor
*/
#define data_max 20
char data_buffer[data_max];
float A;
float B;
void setup(){
Serial.begin(9600);
ask_numbers();
serial_check();
}//end of setup
void loop(){
}//end of loop


void ask_numbers(){
Serial.println("Please enter A");
A = serial_check();
Serial.print("the value you entered is \t");
Serial.print(A);
Serial.println("");
Serial.println("Please enter B");
B = serial_check();
Serial.print("the value you entered is \t");
Serial.print(B);
Serial.println("");
}//end of ask_numbers

float serial_check(){
static byte index = 0;
while(!Serial.available())
{
//wait until user enters the data
}
char input = Serial.read();
if (input != '\r'){
data_buffer[index] = input;
index = index+1;
serial_check();
}else{
data_buffer[index] = 0;//terminate array with NULL to make it string
index = 0;
return atof(data_buffer); // atof --> ascii to float
}
}//end of serial_check



and the result is
function

Saturday, 4 April 2015

LED Brightness Control Via Serial.....


//Author : Kunchala Anil
//Led Brightness control Via Serial
#define ledstep 5
int ledbrightness = 0;
int led[] = {3,5,6,9,10,11};
void setup(){
Serial.begin(9600);
for(int i=0;i<6;i++){
pinMode(led[i],OUTPUT);
}//end of for loop
}//end of setup

void loop(){
Serial.println("enter y to increse the led brightness and n to decrease it");
serial_check();
}//end of loop


//SERIAL_CHECK() FUNCTION
void serial_check(){
while(!Serial.available()){
//wait until user enters the data
}

while(Serial.available()){
char input = Serial.read();
if(input == 'y'){
increase_brightness();
}//end of if
else if(input == 'n')
{
decrease_brightness();
}//end of else if
else {
error();
}//end of else
}//end of while
}//end of serial_check() function

//INCREASE_BRIGHTNESS FUNCTION
void increase_brightness(){
if(ledbrightness < 250){
ledbrightness = ledbrightness + ledstep;
}//end of if
else
{
Serial.println("brightness is maximum resetting it to 0");
ledbrightness = 0;
}//end of else
for(int j=0;j");
Serial.print(ledbrightness);
Serial.println("");
}//end of increase_brightness() function

//MAINTAIN_BRIGHTNESS FUCNTION
void decrease_brightness(){
if(ledbrightness > 0){
ledbrightness = ledbrightness - ledstep;
}//end of if
else
{
Serial.println("brightness is zero resetting it to 250");
ledbrightness = 250;
}//end of else
for(int j=0;j");
Serial.print(ledbrightness);
Serial.println("");
}//end of maintain_brightness() function

//ERROR FUNCTION
void error(){
Serial.println("you entered a wrong character");
}//end of error function

Thursday, 2 April 2015

C/C++ make over in Arduino code

I am neither experienced in Arduino Programming and c language... but i am trying to learn both.
Arduino code is based on the c/c++ language..
anyone who knows simple basics of c language may wonder where the main() entry point function gone?
actually it's there it is hidden under the covers by the Arduino Build environment.
these covers make Arduino an Very easy Language to learn and once you know Arduino it is very hard to learn/program any other controller using C

now i am actually facing the same problem.

the Build process creates an intermediate file that includes the sketch code and the following additional statements.


int main(void)
{
init();
setup();
for(;;)
loop();
return 0;
}


the first thing that happens is a call to an init() function that initializes the Arduino hardware.
next setup() function is called. finally the loop() function is called over and over.
because the loop never terminates, the return statement never executed.

Tuesday, 24 February 2015

Bit vs Byte and Binary Kilo vs Decimal kilo

Bit : binary digit
Byte : combination of 8 binary digits (bits)

the indication of bit is b
the indication of byte is B

k vs K
uppercase letter K stands for binary kilo which is equivalent to 1024(2^10)
lowercase letter k stands for decimal kilo which is equivalent to 1000(10^3)

Thursday, 19 February 2015

Passing Pointers to Function In Arduino

i write the same code in three ways..

1. More descriptive way

void setup(){
Serial.begin(9600); // start the serial communication
int a = 2; // initialise the variable
int *a_ptr = &a; // initialise the pointer and assign the variable address to it
addition(a_ptr); // pass the pointer (which holds the address to the function)
Serial.println(*a_ptr); // print the value in the address which the pointer holds
}//end of setup

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

//Function definition
void addition(int * a_ptr){ // initializing the passing argument as pointer
*a_ptr = *a_ptr+40; // take the value which is stored in address hold in the pointer and add 40 to it
}//end of addition function


2. Do we have to put the names in function argument as b?
this code is also works same as above

void setup(){
Serial.begin(9600); // start the serial communication
int a = 2; // initialise the variable
int *a_ptr = &a; // initialise the pointer and assign the variable address to it
addition(a_ptr); // pass the pointer (which holds the address to the function)
Serial.println(*a_ptr); // print the value in the address which the pointer holds
}//end of setup

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

//Function definition
void addition(int * number){ // initializing the passing argument as pointer
*number = *number+40; // take the value which is stored in address hold in the pointer and add 40 to it
}//end of addition function


3. and One more way to do
avoiding the pointer a_ptr declaration

void setup(){
Serial.begin(9600); // start the serial communication
int a = 2; // initialize the variable a
addition(&a); // pass the address of the variable to the function addition
Serial.println(a); // print the value which is stored in the variable a
}//end of setup

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

//addition function declaration
void addition(int * number){
//we pass the address of a variable to the function as argument
// and it is defined as pointer (which is a normal pointer declaration)

*number = *number+40; // we take the value in address and done computation using it.

}

Sunday, 8 February 2015

Temperature Measurement using K-type Thermocouple and Arduino

For Industrial temperature Measurement Thermocouples are Best choice because of its robust nature, wide range of temperature measurement and no self heating...
But for Beginners like me Dealing with Thermocouples is a nightmare because of all the hurdles of noise reduction and cold junction compensation.

Please go through the wikipedia page or google to know what is noise involvement in thermocouple and cold junction compensation because I barely know what it is and I dont want to deal with them Now.

Why...?

I learn that a nice IC like Max6675 will take care of both of them (But Expensive... ) and it looks like a best route to go through the thermocouple this time.

From datasheet::
The MAX6675 performs cold-junction compensation and
digitizes the signal from a type-K thermocouple. The data is output in a 12-bit resolution, SPI™-compatible,
read-only format.


so what i wanted to do is to just connect thermocouple wires to the IC and let the IC take care of Temp Measurement and get the reading from Max6675 IC's SPI interface....

Ok.. that's a super easy thing and let's go take a look at the Pin configuration
Max 6675 Pin configuration

there are just 8 pins and 3 of them are GND(pin 1) , VCC(pin 4) and one No Connection Pin(Pin 8)

and two pins to connect our thermocouple. T+(Pin 2) and T-(Pin 3)

and Three Pin's to read the Temp data from Ic i.e SPI connection Pins. SCK (pin 5), CS(pin 6) and SO (pin 7)

as already said we get temp data via SPI.. Ok that's good.. Not enough Information to proceed further.
what we wanted to know is In What Format we are going to receive the data?
In datasheet

the max6675 process the reading from thermocouple and transmit the data through the serial interface
Force CS low and apply clock signal at sck to read the result at SO


ok.. what does it mean by force CS to low ? it means simply sending a logic 0 to the CS pin.(Note that CS is a active low input)

after doing that the result will be available at SO. But In what format?

The first bit, D15, is a dummy sign bit and is always
zero. Bits D14–D3 contain the converted temperature in the order of MSB to LSB. Bit D2 is normally low and
goes high when the thermocouple input is open. D1 is low to provide a device ID for the MAX6675 and bit D0
is three-state.


max6675 Serial configuration

so we need total 16 pulses to read the entire data on SO pin and bits D3 - D14 contain Our information.

the code to do the temp measurement is..

#define cs_pin 10
#define so_pin 12
#define sck_pin 13

void setup(){
Serial.begin(9600);
pinMode(sck_pin ,OUTPUT);
pinMode(cs_pin,OUTPUT);
digitalWrite(cs_pin,HIGH);// cs_pin is a active low pin
pinMode(so_pin,INPUT);
}


void loop(){
Serial.println("Getting the Temperature Value");
Serial.print("Temp in C is -->");
Serial.print(get_value());
Serial.println();
}

//defining the get value function
float get_value(){
digitalWrite(cs_pin,LOW);
delay(2);
digitalWrite(cs_pin,HIGH);
//give some time for conversion to take place
delay(220);//220 milli seconds delay - Refer Data Sheet
// now we have our reading ready..
// we can read the data from so line by sending clock pulses from sck pin
read_dummy_bit();
int temp = read_temp_data();
read_open_TC_bit();
read_remaining_bits();
//disable the device
digitalWrite(cs_pin,HIGH);
// calculate the temp value
float temp_value = temp *0.25; // why 0.25 ?
// the resolution of Max 6675 is 0.25 C
return temp_value;
}//end of get_value() function

//read_dummy_bit() function
void read_dummy_bit(){
digitalWrite(sck_pin,HIGH);
digitalRead(so_pin); // read the value and discard it.
digitalWrite(sck_pin,LOW);
}//end of read_dummy_bit() function

//read_temp_data() function
int read_temp_data(){
int value = 0;
for (int i = 11; i <= 0; i--){
// why are we decrementing and shifting in the descending order ..?
// because we receive the MSB first
digitalWrite(sck_pin,HIGH);
value += digitalRead(so_pin) << i;
digitalWrite(sck_pin,LOW);
}//end of for loop
return value;
}//end of read_temp_data() function

//read_opn_TC_bit() function
void read_open_TC_bit(){
digitalWrite(sck_pin,HIGH);
if(digitalRead(so_pin)){
Serial.println("Please check the connection of thermocouple wires");
}//end of else
digitalWrite(sck_pin,LOW);
}//end of read_open_TC_bit() function

//read_remaining_bits() function
void read_remaining_bits(){
for(int i=0;i<=1;i++){
digitalWrite(sck_pin,HIGH);
delay(1);//just leave the value we dont need them
digitalWrite(sck_pin,LOW);
}//end of for loop
}//end of read_remaining_bits() function

I will explain the code in the next post

Saturday, 7 February 2015

74HC4051 Multiplexing/Demultiplexing Analog IC

Even Though 74hc4051 performs both multiplexing and demultiplexing... I dont want to discuss Demultiplexing Now... because i don't need it now. if i need it any time i didn't mind coming back.

multiplexing is choosing from one of various lines (one at a time) and forwards its contents down a single line i.e whatever voltage on it is forwarded to the Common Out/In line


the pinout of 74HC4051 is
Capture

74hc4051 is a useful device which can multiplex and demultiplex up to 8 analog signals into a single analog signal.

in the above pinout A0 to A7 serve as Inputs and A serve as output (pin3)
s0,s1,s2 serve as Address select inputs which are used to send the selected input to Output
E(pin 6) is a active low input which is used to Enable or Disable the IC
Vcc and Gnd are power and ground connections
VEE is the negative supply. which is used to forward the negative input voltage to output
in my case negative voltage is not applied to Arduino So I don't want to bother with
it. so i just connect with the Ground.

So if we connect the pin6,7,8 to the ground and s0,s1,s2 to the arduino output pins and pin3 (A) to the Input port pin we are good to go.

by selecting each combination of s0,s1,s2 we can send the respective input to the output of the Mux....

Multiplexing Max6675 for multiple thermocouple measurements

while i am digging the net to learn something about temperature measurement using thermocouples i got into this ic max6675.

In the starting while reading about thermocouples everywhere they say they are inexpensive but the ic i gone through costs more than 1000 Rs each.. and i don't think it is inexpensive to include the microcontroller to read and the k type thermocouple wire and display. if i included all of them the total cost is no near to the inexpensive.

so i did look for the alternatives in net, they give me so much circuit where i didn't understand one of them so i come back to the maxims max6675.

and again i wondered what if i wanted to measure the temperature at two or more different places with only including cost of k type thermocouple wire.. i think it looks interesting what i wanted to do is

take a max6675 ic that do cold junction compensation and gives the temperature of the thermocouple wires connected to them, i want to multiplex the two or more temperature measurement wires and pass to the max6675 one at each time to measure the temperature.

Capture

Wait a minute..
if I connect an another IC between thermocouple wires and Max6675IC doesn't it form a another 2 junctions which may be result garbage values at the display.....
So
it won't work


I concluded it.. But Suddenly i went through something like thermocouple law of intermediate metals



According to the Thermocouple Law of
Intermediate Metals, illustrated in Figure below,
inserting any type of wire into a thermocouple
circuit has no effect on the output as long as both
ends of that wire are the same temperature, or
isothermal.




Capture

So if i assume that both IC's i.e multiplexer IC and thermocouple cold junction compensation ic is at same temperature, we can measure various temperatures at different locations using single Max6675 IC.

Thursday, 11 December 2014

Arduino ICSP Pins And Boot loader

We can program arduino With USB Cable.. That's nice and super easy way...
Do U Ever wonder How the Arduino Chip [atmel ATmega 328P] is programmed in factory to do all this magical stuff. I got the same doubt and started to digging the Net for it..
In process I came Across ICSP

ICSP is Acronym for In Circuit Serial Programming

As The Name Indicates We can Program Micro controller when the Circuit assembly is completed(In circuit)

from Wikipedia


In Circuit Serial Programming (ICSP) is a method directly programming AvR's and PIC controllers
ICSP is a way that allows us to program the chips when they are in circuits


In arduino It helps in arduino chip Directly with AVR Instructions Without need to arduino IDE. In general Avr Micro controller are programmed with an ICSP, which talks to the micro controller via Serial Peripheral Interface (SPI... Which is an another Long topic we can talk about this in another Post)


In General, ATMega microcontrollers are written in C or assembly Language and programmed via the ICSP interface using another Hardware to upload the Code

So what makes us possible In arduino to upload the code by simply plugging USB cable to our arduino?

that credit goes to the small chunk of program taking a 2k memory in our ATMega Chip which is loaded in factory Named boot loader
Boot Loader allows a Serial USART (Universal Synchronous/ Asynchronous Receiver/Transmitter) to load the arduino Program to the Arduino Without using a separate programmer

In Arduino Uno a secondary Micro controller serves as an interface between a USB cable and serial USART pins on Main Controller[ATMega 368p]
Nick gammon write everything in a one post about Arduino UNO PINOUT checkout here

Boot Loader is basically a HEX file that runs when you power on or reset the board
It is very similar to BIOS that runs on your PC


BIOS : [Basic Input / Ouput System] the bios software is built in PC and it is first software run by PC when you power ON.
the fundamental purpose of BIOS is to Initialize and test the system hardware components and to load the OS from a mass memory device


The BOOT LOADER does two things :
first, it looks around to see if computer is trying to program it. If it is, then It grabs the program From PC and upload it into IC's Memory in specific location so it is not overwrite the boot loader

secondly if computer isn't trying to upload the code, it tells the chip to run the code that's already stored in memory.

Once it locates and runs the program the arduino loops through the program and does as long as board power has power.

after reading all this you may get this small doubt:
Ok.. Boot loader is a chunk of code that runs initially when board power On or Reset to check whether computer is trying to upload the code... But we are not restart / reset the arduino each and every time we try to upload the code...
so how's arduino is doing this
the answer is when you try to upload the code you need to send the UPLOAD command from Arduino IDE, The command instructs USB to Serial chip to reset the Main MCU, hence forcing it into boot loader, then computer immediately begins to send the program contents, which MCU is ready to Receive it Over UART connection.

Serial Monitor with Data logging....

Arduino IDE has an Built-in Serial Monitor. It is a good way to print the some data and debug the program.

what if we wanted to save the monitoring data.. like log the temperature of room in a 12 hours or something like that..?

Serial Monitor come with Arduino IDE doesn't have a data logging capabilities.. so we need an alternative to that..

we can program in python or matlab to save the data... But as a Newbie i only know Arduino Language. I didn't know even know the C or C++ more than Arduino Language.

So I need a much simpler one with out any further coding...

the program I am using with arduino for simple data logging is putty.
it is sufficient enough for simple data logging
you can download it from here
download the exe file and install it.
after installing when you open it it look like


change the connection type to Serial and specify the serial line(com) and speed(baud rate) for com 10 and 9600 baud rate the setting will look like this


click on the Logging and change the following settings as shown in images below



we can change the serial line settings in the Serial category as shown in fig.

then load the following code into the arduino.. using arduino IDE

void setup() {
Serial.begin(9600);
Serial.println("Anil");
}

void loop() {
Serial.println("Kunchala");
delay(1000);

software_reset();
}
void software_reset(){
Serial.println("Do you want to print again?");
Serial.println("enter y or n");
while(!Serial.available()){
}
char in_char = Serial.read();
if (in_char == 'y'){
//if receivd character is y then Reset the arduino
asm volatile("jmp 0");
}
else{
//else call the function to repeat the same procedure
software_reset();
}
}


this code is from my previous post.. you Can Find it in Here

then Close IDE and Open PUTTY configure the above settings and click OPEN

and the log is saved in my desktop file named Putty like this..

Wednesday, 10 December 2014

Pull up and Pull Down Resisitors

All Arduino Pins are Inputs by Default. lets say you wanted to use pin 3 as input to the push button and the circuit will look like this
Push Button Config

if we wanted to send the logic 0 to do specific work we press the push button and it connects the digital pin3 of arduino to the ground.
what is the state of the pin3 when we dnt wanted to send the logic 0 to the circuit?
it connects to the nothing..

"If nothing is connected to the pin and your program reads the state of pin, will it be high or low?? it is difficult to tell" this phenomena is referred to as
floating.

"just because nothing is connected to the input pin doesn't mean it is a logical zero" even it is we dont want to send the logic 0 in present condition when
button is not pushed ,i.e when nothing is connected to the pin.

In this situation Pull up/down resistors are come in handy.

in the above circuit when the button is not pressed the default condition of the circuit has to be logic high(1). so if we connect the vcc to the circuit like this

Pull Up with out resistor

it will full fill our condition to make default position as logic high when button is not pressed.
But When the button is pressed the button it connects the Vcc to Ground, which is called as short, and we have to avoid short circuits. so we need to connect the
resistor between the Vcc and Ground.
Pull Up with resistor

when the button is pressed it connects the input pin directly to the ground, the current flows through the resistor to the ground.



the same scenario is work for Pull Down resistor in this case the default state is low. again the resistor in the circuit is used to avoid the short betweeen vcc and GND
Pull Down Resistor


we can find more information here and here

when to use pull up/down here

Tuesday, 2 December 2014

Resetting Arduino

I ran into situation where I need to reset(?) arduino.. Where adrduino need run the setup() function, to load the new variables to execute the same code.
the initial code is like this.

void setup(){
load some variables
}
void loop(){
run the code according to the varibles
}


I don't want to RESET arduino everytime. so I dig the net to reset the arduino.

I gone through this links

In the link he described it as Dirty Solution
even though i think it meeds my needs. it executes the code from starting point


moves the control to the beginning of the program using an assembly statement jump.


so i write this code to understand myself

void setup() {
Serial.begin(9600);
Serial.println("Anil");
}

void loop() {
Serial.println("Kunchala");
delay(1000);

software_reset();
}
void software_reset(){
Serial.println("Do you want to print again?");
Serial.println("enter y or n");
while(!Serial.available()){
}
char in_char = Serial.read();
if (in_char == 'y'){
//if receivd character is y then Reset the arduino
asm volatile("jmp 0");
}
else{
//else call the function to repeat the same procedure
software_reset();
}
}

the result will look like this..
Capture


Ok... I got what I need But..
What is the meaning of the line
asm volatile("jmp 0");

as previously said it restarts the arduino from starting...,(memory location 0x00)
we can have the answer...

asm volatile is typically used for embedding assembly snippets inside C routines


so it is assembly instruction.

what is the meaning of jmp instruction

The JMP instruction provides a label name where the flow of control is transferred immediately. The syntax of the JMP instruction is:

JMP label


from WIKIPEDIA


the JMP instruction performs an unconditional jump. Such an instruction transfers the flow of execution by changing the instruction pointer register.



this line transfers the execution control to the starting memory location and has nothing to do with any other arduino registers. so registers does not go to default state(INPUT) what actual RESET (by pressing the RESET button).

Monday, 1 December 2014

Declaring the variable as Static

When I digging the net to learn some Serial monitor Basics, I gone through this post
it is really helpful though.

So I think I can Start some.. I started to write it down on arduino IDE to execute it.
So first I literaaly copied it into IDE and executed it and get the OUTPUT as expected..
I think Whoh... I learned everything about Serial communication and i started to code in my own words..

and it ended up something like this..

#define DATABUFFERSIZE 80
char dataBuffer[DATABUFFERSIZE+1]; //Add 1 for NULL terminator
byte dataBufferIndex = 0;
String question_1 = "Enter a value";
void setup(){
Serial.begin(9600);
ask_question(question_1);
while(!getSerialString()){
//wait here
}
int a = atoi(dataBuffer);
Serial.println("the value of A is::");
Serial.println(dataBuffer);

}
void loop(){

}

void ask_question(String question){
Serial.println(question);
}

boolean getSerialString(){
byte dataBufferIndex = 0;
while(Serial.available()){
char incomingbyte = Serial.read();

if(incomingbyte=='\r'){
dataBuffer[dataBufferIndex] = 0; //null terminate the C string
//Our data string is complete. return true
return true;
}
else{
dataBuffer[dataBufferIndex] = incomingbyte;
dataBufferIndex++;
}

}

return false;
}

in the line byte dataBufferIndex
I dont understand the Variable declaration static
so i removed it and still didn't get any error so i think it will execute , and tried to execute it...
and get Output something like this
[caption id="attachment_48" align="alignnone" width="214"]with out static variable in post with out static variable in post[/caption]

as unexpected... the result didn't come it just printing the empty line...

and i didn't know what went wrong.. So I compare the code line to line to find out what went wrong....
the change is i didn't declare it as Static.

I didn't want to use the variable as Static... Why?
because i didnt know what it is.

So I googled about Static and find this in arduino site
Static

The static keyword is used to create variables that are visible to only one function. However unlike local variables that get created and destroyed every time a function is called, static variables persist beyond the function call, preserving their data between function calls.
Variables declared as static will only be created and initialized the first time a function is called.


and unsurprisingly.. I didn't understand a bit in it.
SO i gone to the arduino forum and posted it and got my reply like this:

You are still always resetting dataBufferIndex to 0... I hate repeating myself but.. you have to reset it only after you have received the '\r'.

so i thought byte dataBufferIndex = 0; this line is the wrong line But in the JHaskell's blog he declared it.
as the forum suggests i declared the variable as a global variable.
Quick note: Variables declared Above the setup() function is all global variables
and the code will look like

#define DATABUFFERSIZE 80
char dataBuffer[DATABUFFERSIZE+1]; //Add 1 for NULL terminator
byte dataBufferIndex = 0;
byte dataBufferIndex = 0;
String question_1 = "Enter a value";
void setup(){
Serial.begin(9600);
ask_question(question_1);
while(!getSerialString()){
//wait here
}
int a = atoi(dataBuffer);
Serial.println("the value of A is::");
Serial.println(dataBuffer);



}
void loop(){

}

void ask_question(String question){
Serial.println(question);
}

boolean getSerialString(){
while(Serial.available()>0){
char incomingbyte = Serial.read();

if(incomingbyte=='\r'){
dataBuffer[dataBufferIndex] = 0; //null terminate the C string
//Our data string is complete. return true
return true;
}
else{
dataBuffer[dataBufferIndex] = incomingbyte;
dataBufferIndex++;
}

}


return false;
}

code displays the entered value.. and End of Story.
and Today I accedently look into the STATIC variable i thought i understand something about it

so go back to our first code with variable declaration in getSerialString() function
this function will check whether the '\r' Carriage Return is received or not and return true if the '\r' is received.

Arduino will executed 100's of instruction within time of receiving One character so it will call function the many times while receiving the character and gap between receiving the character.
so the variable dataBufferIndex will initialized to 0 every time it is called. so for every character it will called 100's of times. so we get reply for the function getSerialString() when we received only '\r' character. so when we received '\r' we write the NULL in the dataBuffer in the position of dataBufferIndex which is 0 i.e we are saving a null character in the dataBuffer so program is printing the NULL character itself which is a empty string

So we need a declaration of variable which as to be declared Once and does not reinitialize its value every time it is called and. and according to our program it has to reinitialize when it received '\r' character.

if we look at the explanation of static keyword again:
Static

The static keyword is used to create variables that are visible to only one function. However unlike local variables that get created and destroyed every time a function is called, static variables persist beyond the function call, preserving their data between function calls.
Variables declared as static will only be created and initialized the first time a function is called.

so this is exactly what we need.. So if I change the code using the static variable the code will be

#define DATABUFFERSIZE 80
char dataBuffer[DATABUFFERSIZE+1]; //Add 1 for NULL terminator
byte dataBufferIndex = 0;
String question_1 = "Enter a value";
void setup(){
Serial.begin(9600);
ask_question(question_1);
while(!getSerialString()){
//wait here
}
int a = atoi(dataBuffer);
Serial.println("the value of A is::");
Serial.println(dataBuffer);



}
void loop(){

}

void ask_question(String question){
Serial.println(question);
}

boolean getSerialString(){
static byte dataBufferIndex = 0;
while(Serial.available()>0){
char incomingbyte = Serial.read();

if(incomingbyte=='\r'){
dataBuffer[dataBufferIndex] = 0; //null terminate the C string
//Our data string is complete. return true
return true;
}
else{
dataBuffer[dataBufferIndex] = incomingbyte;
dataBufferIndex++;
}

}


return false;
}


which gives the exact result as second code without global variable...

Sunday, 30 November 2014

Pre Increment (++a) and Post Increment(a++)

I just learned something today... I think it is worth posting

there is a lot of difference between ++a and a++

even though they both get you same result when using with one variable But when we are using used inside an expression they both give the different results
like..

a = 2;
b = 3;
b = a++;
void setup(){
Serial.begin(9600);
Serial.println("b = a++");
Serial.print("a----> \t");
Serial.print(a);
Serial.print("b----> \t");
Serial.println(b);
Serial.println("");
b = ++a;

Serial.println("b = ++a");
Serial.print("a----> \t");
Serial.print(a);
Serial.print("b----> \t");
Serial.println(b);
Serial.println("");
}

void loop(){
}

post increment
if we did y = a++ , it first assign the a value to the y and increment the a value
if a = 2 ; after execution
the value of y = 2
and value of a = 3

pre increment
if we did y= ++a, it first increments the value of a and then assign the value to the y
if a = 7; after execution
the value of y = 8;
the value of a = 8;

it is also same for a-- and --a

and please note that a++ = ++a

Saturday, 29 November 2014

Parsing commands.... Nick Gammons State Machine

I just learn from the Arduino Forum after calling the Serial.end(),the Serial will no longer work. Both Tx and Rx pins in the board will used for General Input and Output.
SO If is there any data present in the Serial Buffer before calling Serial.end(), It will be stay in the buffer but we have no way of knowing where it is in buffer. So we need to empty the buffer before calling the Serial.end().

Quick Note: Serial.flush() is used to Flush the Transmitting Buffer. It has Nothing to do with Receiving Buffer. If we wanted to empty the Serial Receive buffer we can do it by Reading the Data from it using Serial.read()

If we are receiving data with a starting word and ending we can get the data using this code.

int serial_check(){
//this function will check if there is any data in serial buffer format like "R123\r" returns the 123 in int //format
while(Serial.available()){
char data_buffer[50]; // 50 is max index
char in_char = Serial.read();
if(in_char == 'R'){
boolean store_byte = true;
byte in_char_index = 0;//initialize the index to store data
}//end of if


if(store_byte){
//if the store byte is true
if(Serial.read == '\r')
{
//if received character is ending character
data_buffer[in_char_index] = 0; // null terminating the char array to make it String
return atoi(data_buffer);// atoi -- ascii to integer


}//end of if
else{
data_buffer[in_char_index] = Serial.read();// load the data_buffer with incoming data
in_char_index++;// increment the index
}//end of else

}//end of if store byte

}//end of while
}//end of serial_check function


Quick note: If we replace the
data_buffer[in_char_index] = Serial.read() with data_buffer[in_char_index] = in_char we get the return value 0.... and why's that? because we are storing it with starting character.

what if we wanted to distinguish between more than two variables?
we have to write more these if loops


if(in_char == 'R'){
boolean store_byte = true;
byte in_char_index = 0;//initialize the index to store data
}//end of if

for each variable and store the each variable in separate buffer like data_buffer_a and data_buffer_b ..etc

Nick gammon write a excellent code for this
i will try to simplify those things in that code...
I posted this as a initiation ....
now i will try to simplify the things for you.
In Gammon words State machine means looking at each byte in the input stream, and handling it depending on the current state.

what is a state machine?
from wikipedia

It is conceived as an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition; this is called a transition.


from blog.markshed.com
a state machine will read a series of inputs. When it reads an input it will switch to a different state. Each state specifies which state to switch for a given input.

find more information here


if we are getting three variables from serial like t123T567L89
where t ----; time elapsed
T ---- Temperature
L ---- level
and we wanted to Store them in in different variables and process them

OK lets look at the Nick Gammons Code

// the possible states of the state-machine
typedef enum { NONE, GOT_R, GOT_S, GOT_G } states


from wikipedia:
typedef is a keyword in the C and C++ programming languages. The purpose of typedef is to assign alternative names to existing types, most often those whose standard declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another.

we normally declare the variables as

int current_speed ;
int high_score ;


using typedef we can declare the same as

typedef int km_per_hour ;
typedef int points ;


km_per_hour current_speed ; //"km_per_hour" is synonymous with "int" here,
points high_score ; // "points" is also a name we gave alternate to the int

so what's the use of typedef in the above code?
using the typedef we can declare the two different parameters.
like we can declare more variables as

km_per_hour max_speed;
km_per_hour min_speed;


points average;

we can define the structure as

typedef struct {
int data1;
char data2;
} newtype;

we can assigns the values using newtypes

newtype.data1 = 23;
newtype.data2 = A;


Now the enum
Enumerated Types allow us to create our own symbolic names for a list of related ideas.
we can define the enum for colors to represent set of colours we are going to use in our program

enum color {black,red,green,yellow};//do not forget the semicolon

the type name color is used later to define another variables.

wrap around typedef and enum
A type definition is just a simple way of declaring a complex data type in terms of a single symbol name

Enumerations offer a way of createing a new data type that can only take a specific set symbolic integer values Enumerations are far better than #define preprocessing statements for this purpose.

quick note :In C++, in contrast to C, the struct, class, and enum key words are optional in variable declarations that are separate from the definitions, as long as there is no ambiguity to another identifier:
so we don't have to write

typedef enum states { NONE, GOT_R, GOT_S, GOT_G } states;


typedef enum { NONE, GOT_R, GOT_S, GOT_G } states;

it will done our job

let me recap the use of the above lines... just defines the variable data type named state with four variables
NONE,GOT_R,GOT_S,GOT_G as far as I can understand.
from forum:these two lines essentially allow you to create a new variable state where the only four possible values for state are in the braces.

using both limits the variable declaration..?
it will not allow us to declare more variables than those four.
using typedef we can declare additional variables as stated. using enum we declaring the four states variables only... those assign to integers.
next..

// current state-machine state
states state = NONE;
// current partial number
unsigned int currentValue;

note that we just initialize the states type variable with name state and initialize it as NONE which is one of the Four declared variables

void setup ()
{
Serial.begin (115200);
state = NONE;
} // end of setup

Serial communication is starting with baudrate 115200;
I dont know is reinitialization really required here, it really doesn't doing any harm. the code will compile without it also..

quick note: if(Serial.available()) will returns true if there is data in Arduino Rx buffer
and if(Serial) returns true if serial communication enables on arduino. we can disable it by Serial.end()

Next we need to look for loop(). Since i wanted to come in a sequence

void loop ()
{
while (Serial.available ())
processIncomingByte (Serial.read ());


// do other stuff in loop as required

} // end of loop


In loop we continuously check for is there any data in serial Rx buffer or not if there is a data in Serial buffer we call function named processIncomingByte(Serial.read())
it means we calling the function and passing Serial.read() as argument.

quick note: Serial.read() returns the byte of data if there is any data present in Serial Buffer

If we wanted to wait until data comes into Serial buffer we can done this by adding a while loop like this

while(!Serial.available()){
//wait until data received
}

please note that if we add this while loop the code will no longer will be non-blocking. and present this code won't require this while loop.
so next to the ProcessIncomingByte() function

void processIncomingByte (const byte c)
{
if (isdigit (c))
{
currentValue *= 10;
currentValue += c - '0';
} // end of digit
else
{


// The end of the number signals a state change
handlePreviousState ();

// set the new state, if we recognize it
switch (c)
{
case 'R':
state = GOT_R;
break;
case 'S':
state = GOT_S;
break;
case 'G':
state = GOT_G;
break;
default:
state = NONE;
break;
} // end of switch on incoming byte
} // end of not digit

} // end of processIncomingByte

in This function Note the first line

void processIncomingByte (const byte c)


void ---- the function will return nothing
processIncomingByte ----- name of the function
const byte c ---- here byte is a variable type and const means we are passing the argument as a const so
variable is only readable and c is argument passed into function which is the return
value of function Serial.read()
if (isdigit (c))
{
currentValue *= 10;
currentValue += c - '0';
} // end of digit


inside if condition there is a function(?) called isdigit()

the isdigit(C) checks whether the passing argument 'C' is digit or not as name implies.
digits --> 0 1 2 3 4 5 6 7 8 9
it return a value different from zero (i.e., true) if indeed c is a decimal digit. Zero (i.e., false) otherwise.

all the magic is done mostly in these two lines...
currentValue *= 10;
currentValue += c - '0';


if the received byte is digit...
we are doing some math with variables named current value and function argument "c"
the currentValue is declared int but we didn't initialize its value.. Quick search in google returns


Declaring Variables

Before they are used, all variables have to be declared. Declaring a variable means defining its type, and optionally, setting an initial value (initializing the variable). Variables do not have to be initialized (assigned a value) when they are declared, but it is often useful.
int inputVariable1;
int inputVariable2 = 0; // both are correct


so by default it is initialized as 0;
if we are receiving data as is R4500S80G3... if we assume that first we get character then the If loop is not executed..

else
{

// The end of the number signals a state change
handlePreviousState ();

// set the new state, if we recognize it
switch (c)
{
case 'R':
state = GOT_R;
break;
case 'S':
state = GOT_S;
break;
case 'G':
state = GOT_G;
break;
default:
state = NONE;
break;
} // end of switch on incoming byte
} // end of not digit


in the else the function handlePreviousState() is executed.
if we look at the fuction

void handlePreviousState ()
{
switch (state)
{
case GOT_R:
processRPM (currentValue);
break;
case GOT_S:
processSpeed (currentValue);
break;
case GOT_G:
processGear (currentValue);
break;
} // end of switch

currentValue = 0;
} // end of handlePreviousState

look into the state... we declare only 4 possible values for it.
we initialized it as NONE so it Out from switch statement and put a value 0 to the variable currentValue.

next it goes to the switch statement in processIncomingByte function
we are received a character 'R' so it assign GOT_R in to the state and come out of the loop (because of break)

loop in arduino program is executed over and over so we next receive 4 in 4500
it is a digit so if condition is executed.
line 1 currentValue = currentValue * 10 returns 0 since the initial currentValue is 0
line 2 curreentValue = currentValue + c - 0; we add the incoming digit to the currentValue so it becomes 0 + '4' - '0' = 0 + 52 - 48 = 4
if we look at the ASCII chart here the char '4' is represented by decimal value 52 and '0' is represented by decimal value 48.
if we did the calculation then we can get 4 which is the incoming int.

next we receive the char '5' ascii decimal equalent is 53.
currentValue is '4'
so currentValue = currentValue*10 = 40
the currentValue = currentValue + c- 0 = 40 + 53 - 48 = 45

for next two bytes the currentValue become = 4500

next we receive a charactern 'S' so the else is executed...
in the else the first line if code is handlePreviousState () fu
nction
when we first received the R we assigned state variable state = GOT_R;
in hadlePreviousStates() function

case GOT_R:
processRPM (currentValue);
break;

is executed. and currentValue is passes to the functiob processRPM function

In processRPM we are having the value.. so we can further manipulate it..

the full code is


// Example state machine reading serial input
// Author: Nick Gammon
// Date: 17 December 2011

// the possible states of the state-machine
typedef enum { NONE, GOT_R, GOT_S, GOT_G } states;

// current state-machine state
states state = NONE;
// current partial number
unsigned int currentValue;

void setup ()
{
Serial.begin (115200);
state = NONE;
} // end of setup

void processRPM (const unsigned int value)
{
// do something with RPM
Serial.print ("RPM = ");
Serial.println (value);
} // end of processRPM

void processSpeed (const unsigned int value)
{
// do something with speed
Serial.print ("Speed = ");
Serial.println (value);
} // end of processSpeed

void processGear (const unsigned int value)
{
// do something with gear
Serial.print ("Gear = ");
Serial.println (value);
} // end of processGear

void handlePreviousState ()
{
switch (state)
{
case GOT_R:
processRPM (currentValue);
break;
case GOT_S:
processSpeed (currentValue);
break;
case GOT_G:
processGear (currentValue);
break;
} // end of switch

currentValue = 0;
} // end of handlePreviousState

void processIncomingByte (const byte c)
{
if (isdigit (c))
{
currentValue *= 10;
currentValue += c - '0';
} // end of digit
else
{

// The end of the number signals a state change
handlePreviousState ();

// set the new state, if we recognize it
switch (c)
{
case 'R':
state = GOT_R;
break;
case 'S':
state = GOT_S;
break;
case 'G':
state = GOT_G;
break;
default:
state = NONE;
break;
} // end of switch on incoming byte
} // end of not digit

} // end of processIncomingByte

void loop ()
{
while (Serial.available ())
processIncomingByte (Serial.read ());

// do other stuff in loop as required

} // end of loop

and this code won't work with float values.