The maximum current capacity of Arduino digital pin is 20 mA, what if we wanted to power the devices or control the devices using Arduino which consume the current more than 20 mA?
The Basic Alternative is using Transistor to provide a Power supply to the high current/voltage devices.
A transistor will allow you to switch the Motor On and Off safely, as well as to control speed using Pulse Width Modulation techniques
NPN Transistor as a voltage controlled Switch.
Current flows through collector and out of emitter.
By controlling the voltage at the base pin we can control the flow if current in the transistor
The circuit to control the motor using arduino is
When sufficient voltage is applied at the base pin i.e arduino pin Digital High the flow of current is allowed through transistor.
When no voltage is applied at the base the transistor is act like a open switch. There is no current flow between emitter and collector.
In the above circuit the transistor is essentially connecting and disconnecting one terminal of Motor from ground and determining when a complete circuit is made with battery.
We must connect both power supply grounds together to ensure common reference point between voltage levels in two parts of the circuit.
Tuesday, 23 December 2014
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 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
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.
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
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..
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
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
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.
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
we can find more information here and here
when to use pull up/down here
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
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.
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
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.
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
so i write this code to understand myself
the result will look like this..
Ok... I got what I need But..
What is the meaning of the line
as previously said it restarts the arduino from starting...,(memory location 0x00)
we can have the answer...
so it is assembly instruction.
what is the meaning of jmp instruction
from WIKIPEDIA
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).
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..
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..
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[/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..
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
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.
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
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
from blog.markshed.com
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
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
using typedef we can declare the same as
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
points average;
we can define the structure as
we can assigns the values using newtypes
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
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
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..
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
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
// 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
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
in This function Note the first line
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()
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...
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
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..
in the else the function handlePreviousState() is executed.
if we look at the fuction
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
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
and this code won't work with float values.
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.
Monday, 17 November 2014
Serial Communication on Arduino
Just I wanted to you know guy's whatever i write here not is my own brain....
its just a collection of so many resources..... using my own words... I will to try to make it simple.. and reply me if there is any mistakes.. and those mistakes are most welcomed.
It took me almost two weeks to understand a bit of Serial Communication Fundamentals... I thought these are worth mentioning
Ok.. First of all we can communicate with arduino usb cable connected to Pc using digital pins 0 and 1. arduino provides an serial monitor to communicate with it.
In Arduino Uno digital Pins 0 and 1 are called Hardware serial. they communicate with built-in UART in arduino.
we need to know two commands( I don't know they are called commands? tell me if you know) to receive the data from arduino serial.
1.Serial.available()
2.Serial.read()
One Quick Point: Whatever we Send or Receive from the serial is a character. a byte of data.
when we call Serial.available(), it returns us the number of bytes in the Serial Buffer and '0' if there is nothing.
Serial.read(), will returns a single byte or character from the serial buffer and we receive the oldest entry in the buffer.
we can send the data using Serial.print() command.
so if we want to send a data from arduino to pc via Serial communication.. the program will look like this.
I don't know why we write void setup() and void loop().... these are just one of the rules and regulations you have to follow otherwise you won't survive in arduino world. there are reasons for them But I dont wanna know.. why.. I dont wanna go that deep in the arduino ocean.. I am just here touching the water.. I dont wanna go and drown my self in ... I dont even know how to swim yet.
Ok.. now back to the Serial.print("");
when we call the serial.print(""), it will write the data into serialbuffer and send the data byte by byte using interrupts.. and again i dont want to go deep. I wanted to you to know that arduino just load it to that buffer and serial interrupts take care of it. so arduino wont wait until it sends finishing.
we can check this using Serial.flush()
Quick point : Serial.flush() is only for Transmitter Section. It just wait till the transmitter is fully transferred.
To receive data serially first we need to check is there any data available on serial buffer.
we can do this by using Serial.available() command.
Quick point: we don't have control over the serial communication
so to receive data serially the program is like
the above code just receives one byte from Serial and prints it in Serial monitor.
what if we wanted to receive more than one byte.
Quick note: if we used baud rate 9600, then to receive 1 byte it takes 10 micro seconds(approximately).
But to execute a instruction arduino takes less than 50 nano seconds. so it with in the time of receiving a single character, arduino will execute a 100's of executions. So it will be a waste of time to wait for all the serial data to come.
So we dont want waste the arduino time.
so we want to send a signal that all the data is received on arduino and then only we have to read the data. otherwise we will be reading whatever it is present in the buffer, it may be half of our required data or full data if we are lucky... I dont considered myself as lucky.. so i don't wanted to go on that way.
So lets write our program.....
goal of the program : we have to read the full data (Complete String) from the serial Buffer.
Quick note : when we press the "Enter". we are actually sending a carriage return. so by default when we enter data we are sending a data + carriage return
Ok.. lets start the coding.
first we need to have a buffer to store the data which is received in the serial buffer. so we need to initialize the buffer
quick note: in c++ we have to add a null character '0' at the end of the character array, so the compiler will recognize it as end of the array (I am not sure if is it write or wrong let me know if it is wrong)
after that we need to write the setup() function.. goes like this.
if you wanted to learn arduino, besides books.. Arduino forum is a great resource.. there are so many people like us struggling with this little board and its coding..
many users are providing help and showing a way to solve our problems...
there is post by robin2. which is really helpful if you are new to programming language like me Planning and Implementing an Arduino Program.
In loop() function
this is my first i hope you understand it. if you don't.. please let me know.......
its just a collection of so many resources..... using my own words... I will to try to make it simple.. and reply me if there is any mistakes.. and those mistakes are most welcomed.
It took me almost two weeks to understand a bit of Serial Communication Fundamentals... I thought these are worth mentioning
Ok.. First of all we can communicate with arduino usb cable connected to Pc using digital pins 0 and 1. arduino provides an serial monitor to communicate with it.
In Arduino Uno digital Pins 0 and 1 are called Hardware serial. they communicate with built-in UART in arduino.
we need to know two commands( I don't know they are called commands? tell me if you know) to receive the data from arduino serial.
1.Serial.available()
2.Serial.read()
One Quick Point: Whatever we Send or Receive from the serial is a character. a byte of data.
when we call Serial.available(), it returns us the number of bytes in the Serial Buffer and '0' if there is nothing.
Serial.read(), will returns a single byte or character from the serial buffer and we receive the oldest entry in the buffer.
we can send the data using Serial.print() command.
so if we want to send a data from arduino to pc via Serial communication.. the program will look like this.
void setup(){
Serial.begin(9600); //start the Serial communication 9600 is baud rate. baud rate : bits per second
Serial.println("Arduino");//print the data
}
void loop(){
// here loop doing nothing....
}
I don't know why we write void setup() and void loop().... these are just one of the rules and regulations you have to follow otherwise you won't survive in arduino world. there are reasons for them But I dont wanna know.. why.. I dont wanna go that deep in the arduino ocean.. I am just here touching the water.. I dont wanna go and drown my self in ... I dont even know how to swim yet.
Ok.. now back to the Serial.print("");
when we call the serial.print(""), it will write the data into serialbuffer and send the data byte by byte using interrupts.. and again i dont want to go deep. I wanted to you to know that arduino just load it to that buffer and serial interrupts take care of it. so arduino wont wait until it sends finishing.
we can check this using Serial.flush()
Quick point : Serial.flush() is only for Transmitter Section. It just wait till the transmitter is fully transferred.
To receive data serially first we need to check is there any data available on serial buffer.
we can do this by using Serial.available() command.
Quick point: we don't have control over the serial communication
so to receive data serially the program is like
void setup(){
Serial.begin(9600); start serial communication with 9600 baud rate
}
void loop(){
while(Serial.available()){
//wait until user enters data or serial data available
}
char in_byte = serial.read();
Serial.println(in_byte);
}
the above code just receives one byte from Serial and prints it in Serial monitor.
what if we wanted to receive more than one byte.
Quick note: if we used baud rate 9600, then to receive 1 byte it takes 10 micro seconds(approximately).
But to execute a instruction arduino takes less than 50 nano seconds. so it with in the time of receiving a single character, arduino will execute a 100's of executions. So it will be a waste of time to wait for all the serial data to come.
So we dont want waste the arduino time.
so we want to send a signal that all the data is received on arduino and then only we have to read the data. otherwise we will be reading whatever it is present in the buffer, it may be half of our required data or full data if we are lucky... I dont considered myself as lucky.. so i don't wanted to go on that way.
So lets write our program.....
goal of the program : we have to read the full data (Complete String) from the serial Buffer.
Quick note : when we press the "Enter". we are actually sending a carriage return. so by default when we enter data we are sending a data + carriage return
Ok.. lets start the coding.
first we need to have a buffer to store the data which is received in the serial buffer. so we need to initialize the buffer
#define data_buffer_size 40 // maximum number of bytes we may receive
char data_buffer[data_buffer_size +1 ] // +1 is for Null character
quick note: in c++ we have to add a null character '0' at the end of the character array, so the compiler will recognize it as end of the array (I am not sure if is it write or wrong let me know if it is wrong)
after that we need to write the setup() function.. goes like this.
void setup(){
Serial.begin(9600);
}
if you wanted to learn arduino, besides books.. Arduino forum is a great resource.. there are so many people like us struggling with this little board and its coding..
many users are providing help and showing a way to solve our problems...
there is post by robin2. which is really helpful if you are new to programming language like me Planning and Implementing an Arduino Program.
In loop() function
void loop(){
const String question_1 = "Please enter the Data_1 "; // specifying the question to be asked
ask_user_ques(question_1); // this function is used to ask the user question. it passes argument question to the function where it is printed on serial monitor
while(!get_the_response()){;//get_the_response() function is used to check whether data is fully received or not. if total data is received it stored in the data buffer for further use
//wait until get_the_response() returns true
}///end of the while function
// here we received the full data so display it
Serial.print("the data you entered is --------> \t"); // "\t" leaves the Tab space
Serial.print(data_buffer);// print the received data
Serial.println("") // print a line
}//end of the loop function
//here we are going to define our two functions
void ask_user_ques(String question){
Serial.println(question); // print the data on the serial monitor
return;
}//end of the ask_user_ques() function
boolean get_the_response(){
char in_byte; // variable to assign the received character
byte byte_index; // to indicate the number of bytes
while(!Serial.available()){
//wait until user enters the data
// note the "!" sign
}//end of while loop
while(Serial.available()){ // this loop continuously checks is there any data available in the Serial buffer and run the loop until it is empty.
in_char = Serial.read(); // read the character from the serial buffer. we can only read one character at a time
if (in_char == '\r'){ // if received character is the end character... we can change this to our requirements
data_buffer[byte_index] = 0; // terminating the character array with Null Terminator
byte_index = 0// resetting the byte_index so it can read from the stating
return true; // we received the all data return true. so we can read the data from data_buffer variable
}//end of the if
else {// if we received anything else other than ending character
data_buffer[byte_index] = in_char; // add the received character into the data buffer
byte_index++;// increment the byte index which is equal to byte_index = byte_index+1
}
}// end of the while loop
return false; // we do not received the full data Yet.. So Return false
}// end of get_the_response() functtion
this is my first i hope you understand it. if you don't.. please let me know.......
My First Initiation to Embedded World.....
In college i always thought about doing electronic project. But don't know how to do and where to start. really it is for the sake of the name we are studying in a college and i don't even know how the bread board works (Trust me I don't know how the Power and Gnd lines are worked in Bread board ).
But When I accidentally seen the "electronics for you" magazine. and there is a option for free entry in "Electronics Rocks". So i wanted to give a try... why not.... it is a free.. and i never gone to the Bangalore so it is easy to convince the parents to sponsor my trip.
So i go to the event. and I literally don't know what to do there. So I just listens to the all speakers with a blank face(I Don't Understand much but although I tried... Why? Its my first event ).
and due to my poor efficiency in English I don't dare to ask anyone anything( i think you already know that by reading this..... my proficiency in English). So i just listen to them and i understand nothing.
then in the event there comes two controllers(is raspberry pi is a controller?)
1. Arduino
2. raspberry pi
so when i go through them i thought Arduino is a cheaper and better to start with it.
So.. I bought it.
and doing my little tinkering with it. (I don't know much c programming and dont know what is even micro-controller is besides the name)
and here aim going to share what i did with that little board..
But When I accidentally seen the "electronics for you" magazine. and there is a option for free entry in "Electronics Rocks". So i wanted to give a try... why not.... it is a free.. and i never gone to the Bangalore so it is easy to convince the parents to sponsor my trip.
So i go to the event. and I literally don't know what to do there. So I just listens to the all speakers with a blank face(I Don't Understand much but although I tried... Why? Its my first event ).
and due to my poor efficiency in English I don't dare to ask anyone anything( i think you already know that by reading this..... my proficiency in English). So i just listen to them and i understand nothing.
then in the event there comes two controllers(is raspberry pi is a controller?)
1. Arduino
2. raspberry pi
so when i go through them i thought Arduino is a cheaper and better to start with it.
So.. I bought it.
and doing my little tinkering with it. (I don't know much c programming and dont know what is even micro-controller is besides the name)
and here aim going to share what i did with that little board..
Subscribe to:
Posts (Atom)