1

Lets say I have something that sends a command to the Arduino (for example, a PC sending through serial, Ethernet, etc). I want the Arduino to "check" what command it is and run a specific function linked to that command.

I don't need a very explanatory answer, just give me something so I can learn from. A sketch that shows a similar idea would be good, I can try to interpret it and adapt/remake for me.

The idea is to use the Arduino for a lot of different things. Let's say:

  1. Turn a bunch of leds on/off;

  2. Read data from a sensor and send it through Ethernet/I2C/Serial;

  3. Control a servo.

But I want the Arduino to do that when I tell it to (in this case, sending the command through serial, etc). So let's say I send it 1, I'll want it to run the 1 function (turning the LEDs on/off).

I already took a tutorial course on Arduino programming, but I'm clueless on how to do this job.

1

If you want it really barebones and easy, you can checkout the Arduino "Dimmer" example sketch.

Instead of changing the brightness of an attached pin, you could take the input you send it over the serial console and execute various functions, depending on what you receive.

Something like this:

boolean newCommand = false;
void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);

  // other setup stuff here
}

void loop() 
{
  byte command;

  // check if data has been sent from the computer:
  if (Serial.available()) 
  {
    // read the most recent byte (which will be from 0 to 255):
    command = Serial.read();
    // say that you received a new command
    newCommand = true;
  }

  // is there a new command?
  if (newCommand == true)
  {
    // do something depending on what command you received
    switch(command)
    {
      // if you receive command "1", do something
      case 1: functionWhatever();
              break;  // "break" out of the switch. otherwise it would continue executing the following commands as well
      case 2: functionWhatever2();
              break;
      //for cases that are not caught, send out an error
      default: Serial.write("invalid command");
              break;
    }
  }
}

If you want to use an existing library, you might want to check out: EasyTransfer.

It can be used for communication between two Arduinos, which you then can use to execute functions on the other side of the line.

The code itself is relatively simple, so you might be able to adapt it to communicate with a processing script on your computer for example.

  • 1
    Thank you for your answer! The sketch was very clear, and the library seems like a good idea if I'm able to edit it... I'm thinking of connecting a Raspberry Pi and a Arduino via I2C. Would editing the library allow it? I'll try to figure it out later – kodhi.teruya Aug 20 '15 at 19:58
0

If you just want some example code, here is a smallish sketch I wrote that controls some LEDs via a shift register. Exactly how the shift register works isn't important, but you can see the basic idea for taking input from the serial port and decoding it:

#include <SPI.h>

const byte LATCH = 10;

const byte numberOfChips = 4;
const byte maxLEDs = numberOfChips * 8;

byte LEDdata [numberOfChips] = { 0 };  // initial pattern

void refreshLEDs ()
  {
  digitalWrite (LATCH, LOW);
  for (int i = numberOfChips - 1; i >= 0; i--)
    SPI.transfer (LEDdata [i]); 
  digitalWrite (LATCH, HIGH);
  } // end of refreshLEDs


// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 10;

void setup ()
{
  Serial.begin(115200);
  SPI.begin ();
  refreshLEDs ();
} // end of setup

// here to process incoming serial data after a terminator received
void process_data (char * data)
  {
  Serial.print ("Got command: ");
  Serial.println (data);

  // C: clear all bits
  switch (toupper (data [0]))
    {
     case 'C':
        {
        for (int i = 0; i < numberOfChips; i++) 
          LEDdata [i] = 0;
        Serial.println ("All bits cleared.");
        refreshLEDs ();
        return;
        }

    // S: set all bits
    case 'S':
        {
        for (int i = 0; i < numberOfChips; i++) 
          LEDdata [i] = 0xFF;
        Serial.println ("All bits set.");
        refreshLEDs ();
        return;
        }

    // I: invert all bits
    case 'I':
        {
        for (int i = 0; i < numberOfChips; i++) 
          LEDdata [i] ^= 0xFF;
        Serial.println ("All bits inverted.");
        refreshLEDs ();
        return;
        }
    } // end of switch

  // otherwise: nnx 
  //   where nn is 1 to 89 and x is 0 for off, or 1 for on

  // check we got numbers
  for (int i = 0; i < 3; i++)
    if (!isdigit (data [i]))
      {
      Serial.println ("Did not get 3 digits.");
      return;
      }

  // convert first 2 digits to the LED number
  byte led = (data [0] - '0') * 10 + (data [1] - '0');

  // convert third digit to state (0 = off)
  byte state = data [2] - '0';  // 0 = off, otherwise on

  if (led > maxLEDs)
      {
      Serial.println ("LED # too high.");
      return;
      }

   led--;  // make zero relative

   // divide by 8 to work out which chip
   byte chip = led / 8;  // which chip

   // remainder is bit number
   byte bit = 1 << (led % 8);

   // turn bit on or off
   if (state)
     LEDdata [chip] |= bit;
   else
     LEDdata [chip] &= ~ bit;

  Serial.print ("Turning ");
  Serial.print (state ? "on" : "off");
  Serial.print (" bit ");
  Serial.print (led & 0x7, DEC);
  Serial.print (" on chip ");
  Serial.println (chip, DEC);

  refreshLEDs ();
  }  // end of process_data


void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;

  if (Serial.available () > 0) 
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case '\n':   // end of text
        input_line [input_pos] = 0;  // terminating null byte

        // terminator reached! process input_line here ...
        process_data (input_line);

        // reset buffer for next time
        input_pos = 0;  
        break;

      case '\r':   // discard carriage return
        break;

      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop

Example of commands understood by the above code:

C    <-- clear all LEDs
S    <-- set (turn on ) all LEDs
I    <-- invert all LEDs (turn off if on, and vice-versa)
021  <-- turn LED 02 on
020  <-- turn LED 02 off
161  <-- turn LED 16 on

This code processes a 3-digit string as:

nnS

Where "nn" is the LED number and S is the new state (1 = on, 0 = off).


Other examples

  • Your answer actually made me research about a shift register and now I'm actually considering it for saving some output pins on my project, thanks! – kodhi.teruya Aug 20 '15 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.