element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Blog Fast Track to Arduino Programming - Lesson 3 pt 1, Improved Parsing and memory usage (Fully working programs)
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Robert Peter Oakes
  • Date Created: 10 Jun 2014 4:37 AM Date Created
  • Views 625 views
  • Likes 1 like
  • Comments 0 comments
  • fast-track
  • tutorial
  • fast_track_to_arduino_programming
  • intermediate
  • lessons
  • arduino
Related
Recommended

Fast Track to Arduino Programming - Lesson 3 pt 1, Improved Parsing and memory usage (Fully working programs)

Robert Peter Oakes
Robert Peter Oakes
10 Jun 2014

Back to the main intro to the lessons Fast Track to Arduino Programming

 

Below is the intro code for Lesson 3, in order to not make the blog entry too long, part two of lesson three can be found here:

Fast Track to Arduino Programming - Lesson 3 pt 2, Improved Parsing and memory usage (Optimized)

 

The third part in this series is to improve the way we parse the input from the console and make use of SRAM. this initial program is the starting program for this lesson and is presented first to allow you to test and become familiar with its operation.

It is fully working and will read digital inputs, set up PWM outputs and read Analog Inputs, compensating the values to a 0-5V range. There should be nothing new here, I am assuming you will have already run the standard blinky program and know a bit about the analogue capability of the Arduino

The Pins are assigned as follows

 

All command parsing are changeed to use the previously described strcmp() string comparison function, if you do not understand this, please watch the previous video lesson

 

Digital Output pin assignments

          Program Name     Pin Number

#define      D0                     0

#define      D1                     1

#define      D2                     2

#define      D3                     4

#define      D4                     7

#define      D5                     8

#define      D6                     12

#define      D7                     13

 

// define the PWM Pins, Maximum value accepted is 1023

#define      PWM0                3

#define      PWM1                5

#define      PWM2                6

#define      PWM3                9

#define      PWM4                10

#define      PWM5                11

 

The Analogue Inputs are all default. A0 - A5

 

Digital outputs will simply toggle as long as any second parameter is provided, If no second parameter is provided it will return the current state, example command "D0" or "DO 1"

PWM output commands are like this : "PWM 0" to "PWM 1023", if you provide a none numeric second parameter it will not accept it

Analog inputs are simply "A0" through "A5"

 

There are more commands than that listed above, read to program to discover them. A video and second part will be posted in a few days.

 

Now the starting program

/*
Title: Lesson 3. Improved parsing and reduced SRAM consumption - "Case" Statements

Description:  Reading a line of text from the Serial Port and sending to a command process function.
the processing function only echos back to the console for this lesson
This sketch also demonstrates the use of compiler directives to turn on and off blocks of functionality


Date created: 5th June 2014
Created By: Peter Oakes


Additional Comments:


Feel free to use and abuse as you wish, I imply NO Warranty


NOTE: defines take no program space untill used so use instead of ints etc when it will never change


Lessons Available
lesson 0. How big is an Empty Sketch anyway
Lesson 1. Reading the Serial input a line at time
Lesson 2. Parsing the line using  "if else if" statements and == or strcmp
Lesson 3a. Preperation for Improved parsing and reduced SRAM consumption - "Case" Statements


*/
/* Include needed Lbraries */


/* End include libraries */


// Bunch of constants in the form of definitions
// 1 = output debug to serial port, 0 = no debug
#define debug 1
// define the buffer size...
#define serialbufferSize 50
#define commandDelimeters "|,.- "


// Define some Digital pins
// Dont use the PWM capable ones
#define D0 0
#define D1 1
#define D2 2
#define D3 4
#define D4 7
#define D5 8
#define D6 12
#define D7 13


// define the PWM Pins
#define PWM0 3
#define PWM1 5
#define PWM2 6
#define PWM3 9
#define PWM4 10
#define PWM5 11
#define MAXPWM 1023
#define MINPWM 0


#define analogToVolts 5/1023 // Volts per step in ADC
// End of Constants


// Now the real varibles
char inputBuffer[serialbufferSize]   ;
int serialIndex = 0; // keep track of where we are in the buffer
// End of real variables


void setup()
{
  // initialise all the digital outputs
  pinMode(D0, OUTPUT);  
  pinMode(D1, OUTPUT);  
  pinMode(D2, OUTPUT);  
  pinMode(D3, OUTPUT);  
  pinMode(D4, OUTPUT);  
  pinMode(D5, OUTPUT);  
  pinMode(D6, OUTPUT);  
  pinMode(D7, OUTPUT);  


  // initialise all the PWM outputs
  pinMode(PWM0, OUTPUT);  
  pinMode(PWM1, OUTPUT);  
  pinMode(PWM2, OUTPUT);  
  pinMode(PWM3, OUTPUT);  
  pinMode(PWM4, OUTPUT);  
  pinMode(PWM5, OUTPUT);  

  // initialize serial:
  Serial.begin(9600);
  // do other setup here as needed

  // Print some pretty instructions
  Serial.println(" Hello, please ask me something");
  Serial.println("type \"Hello\", \"Goodby\", \"web\" or \"dosomething\"" );
  Serial.println("or \"pwmx where x is from 0 to 5\"" );
  Serial.println("or \"analogx where x is from 0 to 5\"" );
  Serial.println("or \"digitalx where x is from 0 to 7\"" );
  Serial.println("or make up your own command");
  Serial.println();
}


void loop()
{
  // Notice how the main loop is very simple and the functions
  // seperate the logic into easily manageable parts
  if (CheckSerial()) DoCommand(inputBuffer);
  // Do other stuff
}


// Enhanced Command Processor using strtok to strip out command from multi parameter string
boolean DoCommand(char * commandBuffer)
{
  char* Command; // Command Parameter
  char* Parameter; // Additional Parameter
  int analogVal = 0; // additional parameter converted to analog if possible



  // Get the command from the input string
  Command = strtok(commandBuffer,commandDelimeters); // get the command
  Parameter = strtok(NULL, commandDelimeters); // get the parameter if any
  //if there are more than one parameter they will be ignored for now


  // Make sure we have an analog value if we are to allow PWM output
  int outparameter = isNumeric (Parameter);


  //if it is a number then convert it
  if (outparameter)
  {
    analogVal = atoi(Parameter);
    // check the analog value is in the correct range
    if (analogVal < MINPWM || analogVal > MAXPWM) outparameter = false;
  }
  // Standard way to handle commands
  if (strcmp(Command,"Hello")==0){
    Serial.println("Hello back at you ");
    //    Do some other work here
    //    and here
    //    and here
  }
  else if (strcmp(Command,"Goodby")==0){
    Serial.println("Goodby back at you ");
    //    Do some other work here
    //    and here
    //    and here
  }
  else if (strcmp(Command, "dosomething")==0){
    Serial.println("Like what ?? ");
    //    Do some other work here
    //    and here
    //    and here
  }
  else if (strcmp(Command ,"web1")==0){
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-Type: text/html");
    Serial.println("Connection: close");
    Serial.println();
    Serial.println("<!DOCTYPE html>");
    Serial.println("<html><head><title>Hello from www.thebreadboard.ca</title></head>");
    Serial.println("<body><h1>test 1</h1></body>");
    Serial.println("</html>");
    //    Do some other work here
    //    and here
    //    and here
  }
   else if (strcmp(Command, "web2")==0){
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-Type: text/html");
    Serial.println("Connection: close");
    Serial.println();
    Serial.println("<!DOCTYPE html>");
    Serial.println("<html><head><title>Hello from www.thebreadboard.ca</title></head>");
    Serial.println("<body><h1>test 2</h1></body>");
    Serial.println("</html>");
    //    Do some other work here
    //    and here
    //    and here
  }
  else if (strcmp(Command , "web3")==0){
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-Type: text/html");
    Serial.println("Connection: close");
    Serial.println();
    Serial.println("<!DOCTYPE html>");
    Serial.println("<html><head><title>Hello from www.thebreadboard.ca</title></head>");
    Serial.println("<body><h1>test 3</h1></body>");
    Serial.println("</html>");
    //    Do some other work here
    //    and here
    //    and here
  }
   else if (strcmp(Command ,"web4")==0){
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-Type: text/html");
    Serial.println("Connection: close");
    Serial.println();
    Serial.println("<!DOCTYPE html>");
    Serial.println("<html><head><title>Hello from www.thebreadboard.ca</title></head>");
    Serial.println("<body><h1>test 4</h1></body>");
    Serial.println("</html>");
    //    Do some other work here
    //    and here
    //    and here
  }
  else if (strcmp(Command , "web5")==0){
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-Type: text/html");
    Serial.println("Connection: close");
    Serial.println();
    Serial.println("<!DOCTYPE html>");
    Serial.println("<html><head><title>Hello from www.thebreadboard.ca</title></head>");
    Serial.println("<body><h1>test 5</h1></body>");
    Serial.println("</html>");
    //    Do some other work here
    //    and here
    //    and here
  }
// Now some anlog Read Samples
  else if (strcmp(Command, "analog0")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A0));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A0))*analogToVolts);    // read the input pin "A0" is already defined
  }
  else if (strcmp(Command, "analog1")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A1));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A1))*analogToVolts);    // read the input pin "A0" is already defined
  }
  else if (strcmp(Command, "analog2")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A2));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A2))*analogToVolts);    // read the input pin "A0" is already defined
  }
  else if (strcmp(Command, "analog3")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A3));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A3))*analogToVolts);    // read the input pin "A0" is already defined
  }
  else if (strcmp(Command, "analog4")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A4));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A4))*analogToVolts);    // read the input pin "A0" is already defined
  }
  else if (strcmp(Command, "analog5")==0){
    Serial.print("Analog Raw = ");
    Serial.print(analogRead(A5));    // read the input pin "A0" is already defined
    Serial.print(" Volts = ");
    Serial.println(double(analogRead(A5))*analogToVolts);    // read the input pin "A0" is already defined
  }
  //And a few Digitals
  else if (strcmp(Command, "digital0")==0){
    if (outparameter) digitalWrite(D0, !digitalRead(D0));
    Serial.print("Digital 0 = ");
    Serial.println(digitalRead(D0));
  }
  else if (strcmp(Command, "digital1")==0){
    if (outparameter) digitalWrite(D1, !digitalRead(D1));
    Serial.print("Digital 1 = ");
    Serial.println(digitalRead(D1));
  }
  else if (strcmp(Command, "digital2")==0){
    if (outparameter) digitalWrite(D2, !digitalRead(D2));
    Serial.print("Digital 2 = ");
    Serial.println(digitalRead(D2));
  }
  else if (strcmp(Command, "digital3")==0){
   if (outparameter) digitalWrite(D3, !digitalRead(D3));
   Serial.print("Digital 3 = ");
    Serial.println(digitalRead(D3));
  }
  else if (strcmp(Command, "digital4")==0){
    if (outparameter) digitalWrite(D4, !digitalRead(D4));
    Serial.print("Digital 4 = ");
    Serial.println(digitalRead(D4));
  }
  else if (strcmp(Command, "digital5")==0){
    if (outparameter) digitalWrite(D5, !digitalRead(D5));
    Serial.print("Analog 5 = ");
    Serial.println(digitalRead(D5));
  }
  else if (strcmp(Command, "digital6")==0){
    if (outparameter) digitalWrite(D6, !digitalRead(D6));
    Serial.print("Digital 6 = ");
    Serial.println(digitalRead(D6));
  }
  else if (strcmp(Command, "digital7")==0){
    if (outparameter) digitalWrite(D7, !digitalRead(D7));
    Serial.print("Digital 7 = ");
    Serial.println(digitalRead(D7));
  }
  // now allow the PWM Outputs if we have a valid analog parameter
  else if (strcmp(Command, "pwm0")==0  && outparameter ){
      Serial.print("pwm 0 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM0,analogVal);    // Set the PWM 0 output
    }
    // now the PWM Outputs
      else if (strcmp(Command, "pwm1")==0  && outparameter ){
      Serial.print("pwm 1 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM1, analogVal);    // Set the PWM 0 output
    }
    // now the PWM Outputs
      else if (strcmp(Command, "pwm2")==0  && outparameter ){
      Serial.print("pwm 2 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM2, analogVal);    // Set the PWM 0 output
    }
    // now the PWM Outputs
      else if (strcmp(Command, "pwm3")==0  && outparameter ){
      Serial.print("pwm 3 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM3, analogVal);    // Set the PWM 0 output
    }
    // now the PWM Outputs
      else if (strcmp(Command, "pwm4")==0  && outparameter ){
      Serial.print("pwm 4 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM4, analogVal);    // Set the PWM 0 output
    }
    // now the PWM Outputs
      else if (strcmp(Command, "pwm5")==0  && outparameter ){
      Serial.print("pwm 5 = ");
      Serial.println(analogVal);    // read the input pin "A1" is already defined
      analogWrite(PWM5, analogVal);    // Set the PWM 0 output
    }
  // Catch All
  else {
    Serial.print("I dont understand you \nYou said: ");
    Serial.println(commandBuffer);
    //    Do some other work here
    //    and here
    //    and here
  }
// debug code after here
#if debug
if (Parameter != '\0'){
  Serial.print((outparameter)? "Remaining Param is numeric and = " : "Remaining Param is none numeric and = " );
  Serial.println(Parameter);
}
  Serial.print("Free Ram = "); Serial.println(freeRam(), DEC);
#endif
return true;
}


/*
Checks the serial input for a string, returns true once a '\n' is seen
users can always look at the global variable "serialIndex" to see if characters have been received already
*/
boolean CheckSerial()
{
  boolean lineFound = false;
  // if there's any serial available, read it:
  while (Serial.available() > 0) {
    //Read a character as it comes in:
    //currently this will throw away anything after the buffer is full or the \n is detected
    char charBuffer = Serial.read();
      if (charBuffer == '\n') {
           inputBuffer[serialIndex] = 0; // terminate the string
           lineFound = (serialIndex > 0); // only good if we sent more than an empty line
           serialIndex=0; // reset for next line of data
         }
         else if(charBuffer == '\r') {
           // Just ignore the Carrage return, were only interested in new line
         }
         else if(serialIndex < serialbufferSize && lineFound == false) {
           /*Place the character in the string buffer:*/
           inputBuffer[serialIndex++] = charBuffer; // auto increment index
         }
  }// End of While
  return lineFound;
}// End of CheckSerial()


int isNumeric (const char * s)
{
  while(*s)
  {
    if(!isdigit(*s)) return 0;
    s++;
  }
  return 1;
}


#if debug
// check free ram
int freeRam ()
{
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
#endif

 

Back to Intro Blog

Attachments:
Arduino_Lesson_3a___Advanced_Parsing_the_commands_from_Serial.ino.zip
  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube